##链表
1、单链表
什么是单链表?
通过一组任意存储单元来存储线性表中的数据元素
单链表的结构?
一个数据域一个指针域
typedef stuctLNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList
结构体如上
链表优点缺点?
优点:插入和删除元素不需要移动其他元素,效率高O(1)
不要求连续空间,利用率高
缺点:查找和搜索元素效率低,最快O(1),平均O(1)
链表可以解决很多实际的问题,比如约瑟夫问题,和操作系统原理中内存管理问题。
链表的操作
头插法建立单链表
LinkList Create(LinkList &L)
{
LNode *s;
int x
L=(LinkList)malloc(sizeof(LNode));//创建头结点
L->next=NULL;//头结点指空
while(n--)
{
s=(LNode)malloc(sizeof(LNode));//创建一个新节点
s->data=x;//数据域赋值
s-next=L->next;//最后一个结点指空
L-next=s;
}
return L;
}
尾插法建立单链表
LinkList Create(LinkList &L)
{
int x;
L=(LinkList)malloc(sizeof(LNode))
LNode *s,*r=L;//r是表尾指针
while(n--)
{
s=(LNode)malloc(sizeof(LNode));//创建一个新节点
s-data=x;
r->next=s;
r=s;//指向新的表尾结点
}
r-next=NULL;
return L;
}
查找第i个结点
LNode *Get(LinkList &L,int i)
{
int j=1;
LNode *p=L->next;
while(p&&j<i)
{
p=p->next;
j++;
}
return p;
}
查找值为X的结点
LNode *Get(LinkList &L,int x)
{
LNode *p=L->next;
while(p!=NULL&&p->data!=x)
p=p->next;
return p;
}
插入结点操作
{
p=GetElem(L,i-1);//查找插入位置的前驱结点
s-next=p->next;//插入的结点指针域指向原本p指向的后继结点
p-next=s;//原本P的指针域改为指向S
}
前插操作
{
s->next=p->next;
p->next=s;
temp=p->data;
p->data=s->data;
s->data=temp;
}
删除结点的操作
{
p=Get(L,i-1)
q=p->next;
p->next=q->next;
free(q);
}
##双链表
双链表的删除
1、单链表
什么是单链表?
通过一组任意存储单元来存储线性表中的数据元素
单链表的结构?
一个数据域一个指针域
typedef stuctLNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList
结构体如上
链表优点缺点?
优点:插入和删除元素不需要移动其他元素,效率高O(1)
不要求连续空间,利用率高
缺点:查找和搜索元素效率低,最快O(1),平均O(1)
链表可以解决很多实际的问题,比如约瑟夫问题,和操作系统原理中内存管理问题。
链表的操作
头插法建立单链表
LinkList Create(LinkList &L)
{
LNode *s;
int x
L=(LinkList)malloc(sizeof(LNode));//创建头结点
L->next=NULL;//头结点指空
while(n--)
{
s=(LNode)malloc(sizeof(LNode));//创建一个新节点
s->data=x;//数据域赋值
s-next=L->next;//最后一个结点指空
L-next=s;
}
return L;
}
尾插法建立单链表
LinkList Create(LinkList &L)
{
int x;
L=(LinkList)malloc(sizeof(LNode))
LNode *s,*r=L;//r是表尾指针
while(n--)
{
s=(LNode)malloc(sizeof(LNode));//创建一个新节点
s-data=x;
r->next=s;
r=s;//指向新的表尾结点
}
r-next=NULL;
return L;
}
查找第i个结点
LNode *Get(LinkList &L,int i)
{
int j=1;
LNode *p=L->next;
while(p&&j<i)
{
p=p->next;
j++;
}
return p;
}
查找值为X的结点
LNode *Get(LinkList &L,int x)
{
LNode *p=L->next;
while(p!=NULL&&p->data!=x)
p=p->next;
return p;
}
插入结点操作
{
p=GetElem(L,i-1);//查找插入位置的前驱结点
s-next=p->next;//插入的结点指针域指向原本p指向的后继结点
p-next=s;//原本P的指针域改为指向S
}
前插操作
{
s->next=p->next;
p->next=s;
temp=p->data;
p->data=s->data;
s->data=temp;
}
删除结点的操作
{
p=Get(L,i-1)
q=p->next;
p->next=q->next;
free(q);
}
##双链表
为了改善单链表的遍历效率,引入双链表,单链表访问某个结点的前驱结点,需要从头遍历,双链表引入前指针。提高效率
s->next=p-next;
p-next-prior=s;
s->prior=p;
p->next=s;
双链表的删除
p-next=q->next;
q->next->prior=q;
free(q);
##循环链表
##链表的其他问题
1.题目描述:给定链表的头指针和一个节点指针,在O(1)时间删除该节点
思路:用下一个结点的数据域覆盖上一个结点的数据域就可以了,然后删除下一个结点。
void delete(LinkList &L)
{
LNode *pNext=L->next;
if(p==NULL)
{
return NULL;
}
if(p->next==null)
{
return NULL;
}
LNode *cNext=pNext->next;
pNext->data=cNext->data;
pNext->next=cNext->next;
delete(cNext);
}