链式存储结构(链表)
优点1:存储空间动态分配
优点2:插入或删除元素方便,时间复杂度为O(1)
缺点:查找元素不方便,时间复杂度为O(n)
链表由许多个结点组成,每个结点包含它本身存储的元素以及下一个结点地址(指针)
如 1知道2,2知道3,3知道4,以此类推
单链表
第一个结点为头结点 head,最后一个结点为尾结点 tail
头结点不存储数据,尾结点的指针为空,NULL
第一步:创建结构体存储结点信息
struct node{
int data; //数据
node *next; //指针
}
第二步:创建头尾结点
node *head,*tail;
head=new node; //申请空间
tail=head; //头节点既是尾结点
第三步:创建多个新节点
for(int i=1;i<=n;i++){
p=new node;
cin>>p->data;
p->next=NULL; //指针初始化为空
tail->next=p; //将p连接到链表尾部
tail=p; //更新尾结点
}
其中一种打印方式
for(p=head->next;p!=NULL;p=p->next)
cout<data<<" "
查找链表中值为3的结点
p=head->next
while(p->data!=3&&p->next!=NULL){
p=p->next;
}
删除p结点中的下一个结点
p->next=p->next->next;
p结点之后插入一个新结点s
s->next=p->next;
p->next=s;
循环链表
头尾相连的单链表,尾结点的指针指向头结点的数据
tail->next=head;
双向链表
每个结点由指向上一个结点,数据,和指向下一个结点三部分组成
优点是访问,插入,删除变快了,但是以空间换时间
创建方式:
struct node{
int data;
node pre, *next;
}
删除p结点(p为中间结点)
p->pre->next=p->next;
p->next->pre=p->pre;
p结点之后插入一个新结点s
s->next=p->next;
p->next->pre=s;
s->pre=p;
p->next=s;
p结点之前插入一个新结点s
s->pre=p->pre;
p->pre->next=s;
s->next=p;
p->pre=s;