链表
文章目录
链表
一、单链表
1.单链表存储结构
2.1、单链表初始化
2.2、判断链表是否为空*
2.3、销毁单链表L
3 单链表L的表长
4、取值——取单链表中第i 个元素的内容
5、按值查找
6、插入
7、删除*
8、创建单链表*
二、循环链表
三、双向链表
1.双向链表的插入
2.双向链表的删除
前言
提示:这里可以添加本文要记录的大概内容:
顺序表------随机存取
链表---------顺序存取
下面是链表的一些内容。
一、单链表
n个链表有指针链组成一个链表。
单链表 --每个结点只有一个指针域。
1.单链表存储结构
代码如下(示例):
typedef struct lnode {
ElemType date;
struct lnode* next;
}lnode,*linklist;
eg 存储学生学号、姓名、成绩的单列表结点类型定义:
typedef struct {
char num[8];
char num[8];
int score;
}Elemtype;
typedef struct Lnode {
Elemtype data;
struct Lnode* next;
}lnode,*Linklist;
2.1、单链表初始化
代码如下(示例):
status initlist_l(linklist &L){
l=new Lnode;
l->next=NULL;
return ok;
2.2、判断链表是否为空
int listEmpty(linklist L){
if(l->next)
return 0;
else
return 1;
}
2.3、销毁单链表L
status Destroylist_l(linklist &L){
Lnode *p;//linklist p;
while(L)
{
p=L;
L=L->next;
delete p;
}
return ok;
清空链表L
status ClearList(linklist &L){
Lnode *p,*q;//或linklist p,q;
p=L->next;
while(p){
q=p->next;
delete p;
p=q;
}
L->next=NULL;
return ok;
}
*3 单链表L的表长
int ListLength_l(linklist L){//返回L中数据元素个数
linklist p;
p=L->next;
i=0;
while(p){
i++;
p=p->next;
}
4、取值——取单链表中第i 个元素的内容
status GetElem-L(linklist L,int i,ElemType &e){
p=l->next;j=1;
while (p && j < i) {
p = p->next;
++j;
}
if (!p || j > i)
return 0;
e = p->data;
return 1;
5、按值查找
Lnode *LocateElem_L(linklist L,Elemtype e){
p = p->next;j=1;
while (p && p->data != e)
{p = p->next;j++;}
if(p)return j;
else return 0;
6、插入
status listlnsert_l(linklist& L, int i, Elemtype e)
{
p = L; j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;//寻找第i-1个结点,p指向i-1结点
}
if (!p || j > i - 1) return 0;
s = new Lnode; s->data = e;//生成新结点s,将结点s的数据域为e;
s->next = p->next;
p->next = s;
return ok;
}
7、删除
status Listdelete - L(linklist & L, int i, Elemtype & e)
{
p = L; j = 0;
while (p->next && j < i - 1)
{
p = p->next; j++;
}//寻找第i个结点,并令p指向其前驱
if (!(p->next) || j > i - 1)return 0;
q = p->next;//临时保存被删除的结点以被释放
p->next = q->next;//改变删除结点前驱结点指针域
e = q->data;//保存删除结点的数据域
delete q;//释放空间c++
return ok;
}
8、创建单链表
–8.11 头插法
void Creatlist - H(linklist & L, int n) {
L = new Lnode;
L->next = NULL;//建立一个带头结点的单链表
for (int n; i > 0; i--)
{
p = new Lnode;//生成一个新节点c++
//p = (Lnode*)malloc(sizeof(Lnode));生成一个新节点c
cin >> p->data;
p->next = L->next;//插入到表头
L->next = p;
}
}
8.22 尾插法
void Creatlist - H(linklist & L, int n) {
L = new Lnode; L->next = NULL;
r = L;//尾指针r指向头结点
for(int i=0;i<n;i++)
{
p = new Lnode; cin >> p->data;
p->next=NULL:
r->next = p;
r = p;//指向新的尾结点
}
}
二、循环链表
前言
从表中任一结点出发均可以找到表中其他结点;
带尾指针循环链表的合并
linklist connect(linklist ta,linklist tb)
{//假设ta,tb都是非空单循环链表
p=ta->next;//p存表头结点
ta->next=tb->next->next;//tb表头连接ta表尾
delete tb->next;
tb->next=p;
return tb;
}//时间复杂度o(1)
三,双向链表
前言
在单链表的每个结点在增加一个指向其直接前驱的指针域prior,这样的链表就生成了两个方向不同的链;
typedef struct DuLNode{
elemtype data;
struct Dulnode *prior,*next;
}Dulnode,*Dulinklist;
双向链表的插入
void listlnsert_Dul(Dulinklist &L,int i,elemtype e)
{
if(!(p=GetElemp_Dul(L,i)))return error;
s=new Dulnode;s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
}
双向链表的删除
void Listdelete_Dul(Dulink &L,int i,elemtype &e){
//删除带头结点的双向链表L的第i个元素
e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
delete(p);
return ok;
}
总结
链式存储结构的优点:
1、结点空间可以动态申请和释放;
2.数据元素的逻辑次序靠结点的指针来指示,插入和删除时不需要移动数据元素;
五、链式存储结构缺点:
存储密度小,每个结点的指针域需额外占用存储空间。