原理
链表就是通过指针的指向,将内存空间上不连续的点串联在了一起
定义
每个点有各自的数据data,有指向下一个结点的指针next
struct Link {
int data;
Link* next;
};
内存空间申请
c++与c的结构体上的不同
c++:Link* t=(Link*)malloc(sizeof(Link))
c:struct Link* t=(struct Link*)malloc(sizeof(struct Link))
创建单链表
- 常见的创建单链表的方法有两种:头插法和尾插法
头插法形成的单链表是逆序的
尾插法形成的单链表是顺序的
头插法:
Link* headCreateLink() {
//头插法创建单链表
Link* head=NULL;
int data;
while(cin>>data) {
if(data==-1)break;
Link* t=(Link *)malloc(sizeof(Link));
t->data=data;
t->next=head;
head=t;
}
return head;
}
- 即:始终让新的结点成为头结点
尾插法
Link* tailCreateLink(){
//尾插法创建链表
Link* head=NULL,*tail=NULL;
int data;
while(cin>>data){
if(data==-1)break;
Link* t=(Link *)malloc(sizeof(Link));
t->data=data;
t->next=NULL;
if(head==NULL)head=t;
else tail->next=t;
tail=t;
}
return head;
}
- 即:始终让新生成的结点成为尾结点
删除结点
- 删除结点有两种情况,一是删除点在头结点,二是删除点不在头结点
- 一:删除点在头节点,头节点后移即删除
- 二:因为删除当前结点需要当前结点前面结点的next指针指向当前结点的后面结点,才可实现删除,而遍历的时候无法知道当前结点前面的指针。所以我们需要换个思路,站在前一个结点删除当前结点
Link deleteLink(Link* head,int x){
//从链表中删除一些元素
while(head!=NULL&&head->data==x)head=head->next;
if(head==NULL)return head;
Link* p=head;
while(p->next!=NULL){
if(p->next->data==x)p->next=p->next->next;
else p=p->next;
}
return head;
}
插入结点
- 在规定结点的后面插入一个结点。
通过指针的互相指向即可实现插入
假设存在要在p指针后插入一个结点t
让t->next=p->next,p->next=t即可
顺序相反不行,因为p->next若被先改成了t,t就找不到p原来的next了
Link* insertLink(Link* head,Link* goal,int data){
Link* p=head;
while(p!=NULL&&p!=goal)p=p->next;
if(p==NULL)return noFind;
Link* t=(Link*)malloc(sizeof(Link));
t->data=data;
t->next=p->next;
p->next=t;
return head;
}