期末复习——单链表及其基本操作

单链表的概念

定义:采用链式存储结构的线性表称为链表

实现角度可以分为:
静态链表、动态链表;
链接方式可以分为:
单链表、双向链表、循环链表;

单链表:链表中的每一个结点只有一个指针域。

单链表包括两个域:

  • 数据域:用来存储结点的数据值;
  • 指针域:用来存储数据元素的直接后继的地址。

结点的定义:

typedef struct Node{
	ElemType data;
	struct Node *next;
}LNode,*LinkList;

基本操作

单链表建立

在这里插入图片描述
有时为了操作方便,在单链表的第一个结点之前附加一个结点,称为头结点。头结点的数据域可以存储标题、表长等信息,也可以不存储任何信息,其指针域存储第一个结点的首地址。

头指针变量定义:
LinkList H;p=(LinkList) malloc(sizeof(LNode));
表示申请一块LNode类型的存储单元的操作,并将其地址赋值给变量p;
free( p) 表示释放指针p所指向的结点空间。

1. 头插法建表

在链表的头部插入结点建立单链表,首先申请一个头结点,并且将头结点指针域置空(NULL);然后每读入一个数据元素则申请一个结点,并插在链表的头结点之后。
在这里插入图片描述
算法:时间复杂度为O(n)

LinkList CreateFromHead(){
	LinkList L;
	LNode *s;
	int x;
	int flag=1;
	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL;
	scanf("%d",&x);
	while(x!=-1){
		s=(LNode*)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;
		L->next=s;
		scanf("%d",&x);
	}
	return L;
}

2. 尾插法建表

在单链表的尾部插入结点建立单链表,增加一个指针r来始终指向链表中的尾结点,以便能够将新结点插入到链表的尾部。首先初始化一个空表,使指针r指向头结点,然后插入一个新结点到r的后一个结点,同时r指向新结点。
在这里插入图片描述
算法时间复杂度为O(n)

LinkList CreateFromTail(){
	LinkList L;
	LNode *r,*s;
	int x;
	L=(LNode*)malloc(sizeof(LNode));
	L->next=NULL;
	r=H;
	scanf("%d",&x);
	while(x!=-1){
		s=(LNode*)malloc(sizeof(LNode));
		s->data=x;
		s->next=r->next;
		r->next=s;
		r=s;//让r指向尾结点
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
}

存储空间的分配和释放
如果在一个单链表里面插入一个结点,那么该新结点的存储空间从何处来呢?还有当把这个结点删掉以后,这个存储空间又把它归还给谁呢?
用下面几个函数就可以实现:
malloc 函数
void *malloc(unsigned int size);
calloc 函数
void *calloc(unsigned n,unsigned size);
free函数
void free(void *p)。

单链表插入

在这里插入图片描述
要在带头结点的单链表L中第i个数据元素之前插入一个数据元素e,需要首先在单链表中找到第i-1个结点并由指针pre指示,然后申请一个新的结点并由指针s指示,其数据域的值为e,并修改第i-1个结点的指针使其指向s,然后使s结点的指针域指向第i个结点
首先要找到要进行操作的前驱结点,然后改链的操作比较重要,先将待插入的结点s的next指向原先结点的下一个位置,再将原先结点的next指向待插入的s.
在这里插入图片描述
算法:

void InsList(LinkList L,int i,ElemType e){
	LNode *pre,*s;
	int k=0;
	pre=L;
	while(pre!=NULL&&k<i-1){
		pre=pre->next;
		k=k+1;
	}
	if(k!=i-1){
		printf("插入位置不合理!");
		return ;
	}
	s=(Node*)malloc(sizeof(Node));
	s->data=e;
	s->next=pre->next;
	pre->next=s;
}

单链表删除

欲在带头结点的单链表L中删除第i个结点,则首先要通过计数方式找到第i-1个结点并使pre指向第i-1个结点,而后删除第i个结点并释放结点空间。
在这里插入图片描述
删除之后要free释放掉空间,不然以后这个空间就不能被其他结点所分配。
在这里插入图片描述
删除算法:

void DelList(LinkList L,int i,ElemType e){
	LNode *pre,*r;
	int k=0;
	pre=L;
	while(pre!=NULL&&k<i-1){
		pre=pre->next;
		k=k+1;
	}
	if(k!=i-1){
		printf("删除结点的位置i不合理!");
		return ERROR;
	}
	r=pre->next;
	pre->next=pre->next->next;
	free(r);
	return OK;
}

猜你喜欢

转载自blog.csdn.net/ITmincherry/article/details/106635415