本文旨在设计一个简单链表及其读取,插入和删除操作。
首先是链表的设计,笔者设计的链表比较简单,每个节点仅包含一个自定义类型ElemType的值和指向下一个节点的结构体指针,其实本质上来讲,节点就是一个包含着不同元素的结构体,而这个结构体里又包含着指向下一个结构体的指针,像钩锁一样将不同的节点连接在一起,就构成了一个链表。
typedef int ElemType;
typedef struct Node{
ElemType value;
struct Node* next;
}Node;
typedef struct Node* LinkList;
其中需要注意的是,在创建链表时一定要正确连接节点。那么当把当前节点指向一个新节点时,我们一定要先创建新节点,并为其分配内存,这是非常容易忽略的一点,如果没有的话,那么链表就不能正确形成。
还需要注意的是,在创建链表代码的末尾,一定要释放链表中的内存,防止内存泄漏。建议使用循环来释放每个节点的内存。
下面是一个简单链表的创建和赋值。
int main(){
LinkList p,head,last;
p = (LinkList)malloc(sizeof(Node));
head = p;
int t = 1,Length = 10;
for(t = 1;t <= Length;t++){
p->value = t;
//要想将节点正确连接,需要先创建新节点,然后再指向新节点
p->next = (LinkList)malloc(sizeof(Node));
last = p;
p = p->next;
}
//printf(" head节点值为 %d\nlast节点值为 %d\n",head->value,last->value);
//释放每个节点的内存
for(p = head;p!=NULL;p = p->next){
LinkList point = p;
free(point);
}
}
接着是链表的读取操作。
实现链表的读取,需要知道表头head和要读取的位置i,其中表头就是链表的第一个节点。至于如何找head,这点是比较简单的就不再赘述了。所以当我们知道了要读取的位置i后,就可以通过遍历,使用循环不断遍历下一个节点,然后在第i个节点停止,我们便找到了要读取的位置所代表的节点,那么就可以轻松地读取到位置i存储的值了。
出于偷懒的目的,笔者使用void函数来实现链表的读取操作。
void ElemGet(LinkList head,int i);
//读取函数的声明
void ElemGet(LinkList head,int i){
LinkList p;
int t = 0,judge = 1;
for(p = head;p&&t<i;p = p->next){
t++;
if(t==i){
printf("第%d个节点的值为%d\n",i,p->value);
judge = 0;
break;
}
}
if(judge)
printf("i非法值!");
}
然后是链表的插入操作。
实现链表的插入,我们只需知道表头head,要插入的值value和要插入的位置i。为了将value插入在第i个节点和第i+1个节点之间,我们需要先从头遍历到第i个节点p。在遍历结束之后,需要新定义一个空节点medium,将其插入。想象一下火车车厢,当插入新车厢时,仅需将新车厢的头与上一节的尾相连,将新车厢的尾与下一节的头相连,链表也是如此。
void ElemInsert(LinkList head,ElemType value,int i);
//函数的声明
void ElemInsert(LinkList head,ElemType value,int i){
LinkList p = head;
int t = 0;
for(p = head;p&&t<i-1;p = p->next){
t++;
}
LinkList medium;
medium = (LinkList)malloc(sizeof(Node));
medium->next = p->next;
p->next = medium;
medium->value = value;
}
最后便是链表的删除操作。
正如上文所讲,我们仅需知道表头head和要删除的位置i便能实现。再拿火车车厢来举例,当我们发现这个新车厢不对号要把它给拆卸掉该怎么做?是不是得将它的头与上一节的尾断开来,再将它的尾与下一节的头断开来。如此我们便拆卸掉了这一节车厢,而链表则更省力气,只用动手敲敲代码便能拆卸掉。
void ElemDelete(LinkList head,int i);
//函数的声明
void ElemDelete(LinkList head,int i){
LinkList p = head;
int t = 0;
for(p = head;p&&t<i-2;p = p->next){
t++;
}
p->next = (p->next)->next;
free(p->next);
}
以上便是本文的全部内容了,在感谢阅读的同时,也欢迎大家批评指正。