链表的特征:
1逻辑连续,但物理位置不连续;
2由数据域和指针域组成;数据域用于存放数据元素本身的信息,指针域用于存放后续节点的地址;例如:
typedef struct list{
int data; //data是所存放的数据元素,不一定是int,还可以是其他类型;
struct list *next; //下一结点的地址
} List;
链表的创建:
1用malloc函数为链表的头指针分配空间(在createLinklist1() 函数中完成,返回链表的头指针);
List *createLinklist1()
{
List *head;
int e;
head=(List*)malloc(sizeof(List));
scanf("%d",&e);
head->data=e;
createLinklist2(head);
return head;
}
2创建链表的后续元素(通过迭代完成),完成这一功能的函数如下所示,最后一个元素的next指针要指向NULL;在实现功能1的函数中调用这一函数,可以创建一个链表;
void createLinklist2(List *node)
{
int e;
node->next=(List*)malloc(sizeof(List));
scanf("%d",&e);
node->next->data=e;
if(e==0)
{ node->next->next=NULL;
return;}
createLinklist2(node->next);
}
打印链表的数据:
使用的仍然是迭代的方法,跳出条件是next指针为空(NULL);
void print(List *node)
{
printf("%d/n",node->data);
if(node->next==NULL)
{return;}
else
print(node->next);
}
以下代码实现创建一个链表,链表的数据是一连串整数,当输入0的时候输入停止,将链表内容输出;
#include<stdio.h>
#include<stdlib.h>
typedef struct list{
int data;
struct list *next;
} List;
List *createLinklist1();
void createLinklist2(List *node);
void print(List *node);
main()
{
print(createLinklist1());
}
List *createLinklist1()
{
List *head;
int e;
head=(List*)malloc(sizeof(List));
scanf("%d",&e);
head->data=e;
createLinklist2(head);
return head;
}
void createLinklist2(List *node)
{
int e;
node->next=(List*)malloc(sizeof(List));
scanf("%d",&e);
node->next->data=e;
if(e==0)
{ node->next->next=NULL;
return;}
createLinklist2(node->next);
}
void print(List *node)
{
printf("%d/n",node->data);
if(node->next==NULL)
{return;}
else
print(node->next);
}
链表删除指定节点:
1找到所要求的节点的前一个节点的指针(若是第一个,则直接返回头指针);
2删除指定节点;
3将前一节点的next指针指向下一结点;
为了便于使用链表,删除指定节点的函数应该返回链表的头指针;
删除指定节点有三种情况:
1删除的是第一个节点;将头指针指向第二个节点,再销毁第一个节点,返回头指针;
2删除链表中间的节点:这通过指定节点的前一个节点的next指针实现;再销毁指定节点;返回头指针;
3链表中无要删除的节点;仍旧返回头指针。
找到目标节点的前一节点的指针,用如下函数实现:
List *search(List *node,int i)
{
if(node->next->data==i||node->data==i)
{return node;}
if(node->next==NULL&&node->data!=i)
{
return NULL;
}
search(node->next,i);
}
注:这里不区别目标节点是第一个还是链表中的节点,这由调用它的删除函数判断;
删除函数:
List* del(List *head,int i)
{
List *r,*del;
if(search(head,i)==head)
{ del=head;
head=head->next;
free(del);
return head;
}
else
{ r=search(head,i);
del=r->next->next; //中间指针变量指向下下个节点
free(r->next); //销毁下个节点
r->next=del; //通过中间指针变量将前一节点的next指针指向下下个节点
return head;}
}
注意:在第2种情况的删除时,要先中间指针变量指向下下个节点,再销毁下个节点,否则链表就断了,因为下个节点的next指针才有下下个节点的地址。销毁后通过中间指针变量将前一节点的next指针指向下下个节点即可。这是最关键的三句。
完整代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct list{
int data;
struct list *next;
} List;
List *createLinklist1();
void createLinklist2(List *node);
void print(List *node);
List *search(List *node,int i);
List* del(List *head,int i);
main()
{
int i;
List *p;
p=createLinklist1();
print(p);
scanf("%d",&i);
p=del(p,i);
print(p);
}
List *createLinklist1()
{
List *head;
int e;
head=(List*)malloc(sizeof(List));
scanf("%d",&e);
head->data=e;
createLinklist2(head);
return head;
}
void createLinklist2(List *node)
{
int e;
node->next=(List*)malloc(sizeof(List));
scanf("%d",&e);
node->next->data=e;
if(e==0)
{ node->next->next=NULL;
return;}
createLinklist2(node->next);
}
void print(List *node)
{
printf("%d/n",node->data);
if(node->next==NULL)
{return;}
else
print(node->next);
}
List *search(List *node,int i)
{
if(node->next->data==i||node->data==i)
{return node;}
if(node->next==NULL&&node->data!=i)
{
return NULL;
}
search(node->next,i);
}
List* del(List *head,int i)
{
List *r,*del;
if(search(head,i)==head)
{ del=head;
head=head->next;
free(del);
return head;
}
else
{ r=search(head,i);
del=r->next->next;
free(r->next);
r->next=del;
return head;}
}
链表节点的添加:
分两种情况:
1在链表表头位置插入,插入的节点作为链表的第一个节点;
2在表中插入;
分为两个函数实现:
在表头位置插入(由于头指针会改变,所以要返回一个指针类型)
List* insert_head(List *head,int item)
{
List *q;
q=(List*)malloc(sizeof(List));
q->next=head;
q->data=item;
return q;
}
在表中插入:
void insert_body(List*head,int item,int a) //item表示要插入的内容,a表示插入位置前面那个节点的内容
{ List *p,*q;
q=(List*)malloc(sizeof(List));
p=search(head,a);
if(p==NULL)
{printf("This item does not exist/n");
return;}
q->next=p->next->next;//这三句是核心,由于借用的是前面写的search函数,返回的是a前面那个节点的指针,所以要有两个next
p->next->next=q; //
q->data=item; //
}
完整代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct list{
int data;
struct list *next;
} List;
List *createLinklist1();
void createLinklist2(List *node);
void print(List *node);
List *search(List *node,int i);
List* del(List *head,int i);
void insert_body(List*head,int item,int a);
List* insert_head(List *head,int item);
main()
{
int i,a,b;
List *p;
p=createLinklist1();
print(p);
printf("Please enter the item you want to delete:/n");
scanf("%d",&i);
p=del(p,i);
print(p);
while(1)
{
printf("you want to:1insert an item after an elemen 2insert an item at the beginning/n ");
scanf("%d",&i);
switch(i)
{
case 1:
printf("enter:1the item you want to insert 2after which item should you insert the item?/n");
scanf("%d %d",&a,&b);
insert_body(p,a,b);
print(p);
break;
case 2:
printf("Please enter the item you want to insert/n");
scanf("%d",&a);
p=insert_head(p,a);
print(p);
break;
}
}
}
List *createLinklist1()
{
List *head;
int e;
head=(List*)malloc(sizeof(List));
scanf("%d",&e);
head->data=e;
createLinklist2(head);
return head;
}
void createLinklist2(List *node)
{
int e;
node->next=(List*)malloc(sizeof(List));
scanf("%d",&e);
node->next->data=e;
if(e==0)
{ node->next->next=NULL;
return;}
createLinklist2(node->next);
}
void print(List *node)
{
printf("%d/n",node->data);
if(node->next==NULL)
{return;}
else
print(node->next);
}
List *search(List *node,int i)
{
if(node->next->data==i||node->data==i)
{return node;}
if(node->next==NULL&&node->data!=i)
{
return NULL;
}
search(node->next,i);
}
List* del(List *head,int i)
{
List *r,*del;
if(search(head,i)==head)
{ del=head;
head=head->next;
free(del);
return head;
}
else
{ r=search(head,i);
del=r->next->next;
free(r->next);
r->next=del;
return head;}
}
void insert_body(List*head,int item,int a)
{ List *p,*q;
q=(List*)malloc(sizeof(List));
p=search(head,a);
if(p==NULL)
{printf("This item does not exist/n");
return;}
q->next=p->next->next;
p->next->next=q;
q->data=item;
}
List* insert_head(List *head,int item)
{
List *q;
q=(List*)malloc(sizeof(List));
q->next=head;
q->data=item;
return q;
}