当前位置:   article > 正文

C语言数据结构之链表详细解析_typedef struct lnode { elemtype data; struct lnode

typedef struct lnode { elemtype data; struct lnode *next; }lnode,*linklist

单链表

1.单链表存储类型的描述

单链表由一个个的相互独立的结点构成,每个结点均为一个结构体,每个结构体都包含两个结构体成员,分别为数据域data和指针域next。数据域用于存放链表的数据,指针域用于存储其后继节点的地址。
单链表的节点的结构如下
单链表的节点的结构
单链表的节点的结构体(数据域+指针域)

typedef struct LNode {
Elemtype data;
Struct LNode *next;
}LNode,*Linklist
  • 1
  • 2
  • 3
  • 4

2.单链表的建立

单链表的建立分为两种方式——头插法和尾插法

1.头插法(新生成的节点插在头指针和头结点之间)
头插法图示(红色线表示新增的指针)
头插法图示1. 核心步骤

s->data=x;
s->next=L->next;
L->next=s;
  • 1
  • 2
  • 3

2.程序演示

Linklist CreateList1(Linklist &L){
Linklist s;										//在结构体声明的时候时候已经将linklist声明为指针类型
int x;
L=(Linklist) malloc(sizeof(LNode));  //生成头结点
L->next=NULL;								//头结点的next域置为空  
Scanf(“%d”,&x);
While(x!=9999){				//输入9999停止生成节点
		S=(Linklist)malloc(sizeof(LNode));   //生成一个新的节点
		s->data=x;							//给新的节点的data域赋值,值为上述输入的x
		s->next=L->next;					//将新生成的节点的next域指向头结点
		L->next=s;							//头指针指向新生成的节点
		Scanf(“%d”,&x);					//循环条件
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.尾插法:(新生成的节点插在当前链表的最后一个节点之后)
头插法图示(红色线表示新增的指针)
尾插法图示
1.核心步骤(新声明一个指针R指向当前链表的最后一个节点)

s->data=x;		//将要插入的值放入新声明的节点中
r->next=s;		//将新的节点与链表的最后一个节点连接起来
r=s;			//让r指向新的链表的最后一个节点
  • 1
  • 2
  • 3

2.程序演示:

Linklist CreateList2(Linklist &L){
	int x;
	Linklist s,r;			//s用于指向新生成的节点  r指向当前链表的最后一个节点
	r=L;
	L=(Linklist)malloc(sizeof(LNode));    //生成头结点
	Scanf(“%d”,&x);
	while(x!=9999){
		s=(Linklist)malloc(sizeof(LNode));		//生成新的节点
		s->data=x;
		r->next=s;
		r=s;
		scanf(“%d”,&x);
}
r->next=NULL;					//将链表的最后一个节点的next域置为空
return L;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.单链表的查找

1.按值查找(在链表中确定某值是否存在,若存在确定位置)

Lnode *LocalElem(Linklist L,ElemType e){
	LNode *p;
	p=L->next;
	while(p!=NULL&&p->data!=e){
		p=p->next;
}
return p;			//返回所查到的值得指针
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.按序号查找(找到第x个节点)

 LNode * GetElem(Linklist L,int i){
	LNode *p;
	P=L->next;
	int j;
	if(i=0)		//判断要找的节点的位置,规定:0表示头结点
		return p;
	if(i<0)			//位置小于0不合法
		return NULL;
	while(j<i){
		p=p->next;
		j++;
}
return p;			//返回节点位置
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4.单链表的插入、删除

1.插入节点
(1)插入图示
插入节点图示注:指针的变动顺序必须是1-2,顺序不能互换,若先连接2,则新节点及新节点以后的节点则没有指针能指向他们,即丢失了后边的所有节点。
(2)核心代码:

R=GetElem(L,i-1);		//找到插入位置
S->next=R->next;		//连接新节点S和后边的节点(即图中步骤1),此时R原有指针没变,可以找到后边的节点
R->next=s;				//R连接新节点S(即图中步骤2)
  • 1
  • 2
  • 3

2.在……之前插入
1.例如在第四个节点之前插入节点等同于在第三个节点前插入,调整GetElem这个函数的参数即可。
2. 也可以在第四个节点以后插入新的节点再交换第四个节点和第五个节点的值。
核心代码:

//在……之后插入一个节点 
s->next=p->next;
p->next=s;
//交换两个元素的值
temp=p->data;
p->data=s->data;
s->data=temp;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.删除节点
(1)删除图示
删除节点图示
(2)核心代码

S=GetElem(L,i-1);   //找到要删除的节点
e=S->data;		//通过e保存要删除的节点的data值
R->next=S->next;			//删除节点
free(S);				//释放删除的节点
  • 1
  • 2
  • 3
  • 4

5.双链表

双链表图示:
双链表图示
1.结构体:

typedef struct DNode{
ElemType data;
struct DNode *piror;
struct DNode *next;
}DNode,*DLinklist;
  • 1
  • 2
  • 3
  • 4
  • 5

双链表的插入:(核心在于先解决没有指针指着的后边的那个节点)
例如:在第二个节点后插入一个新的节点
(1)插入图示
双链表插入节点指针的改变步骤为图中的1-2-3-4,其中:1,2的顺序可互换,3,4的顺序可互换
(2)核心代码

s->next=R->next;  //s表示新插入的节点,p表示第三个节点
R->next->piror=s;
R->next=s;
s->piror=R;
  • 1
  • 2
  • 3
  • 4

双链表的删除:
例如:删除第二个节点
(1)删除图示
双链表删除节点其中:指针的变动顺为1-2或者2-1
(2)核心代码

R->next=S->next;   //p表示第三个节点,q表示第四个节点,即要删除的节点
S->next->piror=R;
free(S);      //这一步释放节点一定不要忘了
  • 1
  • 2
  • 3

循环链表:
单循环链表:尾节点的next域指向头结点
双循环链表:头结点的piror域指向尾节点,尾节点的next域指向头结点

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/429845
推荐阅读
相关标签
  

闽ICP备14008679号