数据结构与算法—— * 链表--- 单链表 *

Posted 玄澈_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法—— * 链表--- 单链表 *相关的知识,希望对你有一定的参考价值。


 

 链表的每一个结点中只包含一个指针域

 优点 : 储存空间利用高效

 举例来说:

typedef struct student
	int id;		//学生编号
	char* name; //学生名称

	//指向下一结点的指针
	struct Student* pNext;
Student;

与之相反的是多链表

typedef struct student
	int id;		//学生编号
	char* name; //学生名称

	//指向下一结点的指针
	struct Student* pNext;
	struct Student* qNext;
Student;

 获取第i个结点的数据元素

  1. 声明一个结点指针p指向链表的第一个结点a1,初始化j从1开始
  2. 当j < i 时,遍历链表,让p的指针向后移动,不断指向下一个结点,j 累加 1
  3. 当链表末尾 p 为空时,则说明第 i 个元素不存在;否则查找成功,返回结点 p 的数据

 1,定义数据元素

//定义数据元素
typedef struct student
	int id;		
	char* name; 
ElementType;

 2,定义顺序表结构

typedef struct 
	ElementType dates[MAX_SIZE];   //当前顺序表中的数据集合
	int length;					   //当前顺序表中的元素个数

SeqList;

3,定义链表的结点(包括数据域和指针域)

typedef struct Node 
	ElementType date;  //数据域
	struct Node* node; //指针域,指向下一个结点
Node;

4,设置头结点

我们在定义链表时,习惯性的会定义头结点,以便统一链表结点的插入和删除操作

typedef struct Linklist 
	Node* next;  //头指针
	int length;
Linklist;
  1. 如果链表有头结点,next就指向头结点,没有就指向第一个结点
  2. 链表的长度初始值为0

插入数据元素 

在第i个结点后插入数据元素

  1.  创建一个空节点,分配内存空间,设置数据元素
  2. 获取第i个结点,设置新结点的后继结点为该结点的后继结点
  3. 设置第i个结点的后继结点为该结点

1,创建空节点并为数据域赋值

	//创建空节点并为数据赋值
	Node* node = (Node*)malloc(sizeof(Node));
    node -> date = element;
    node -> next = NULL;

 2,通过循环找到要插入的结点

	for (int i = 1; currNode && i < pos - 1; i++)
	
		currNode = currNode->next;
	

3,将结点插入并对接前面的结点

	if (currNode) 
		node->next = currNode->next;
		currNode->next = node;
		linkList->length++;
	

初始化链表 

void InitLinkList(LinkList* linkList, ElementType* dateArrar, int length)

	for (int i = 0; i < length; i++) 
		InsertLinkList(linkList, i + 1, dateArrar[i]);
	

打印链表

void PrintLinkList(LinkList* linklist)

	Node* node = linklist->next;
	if (!node)
	
		printf("链表为空!\\n");
		linklist->length = 0;
		return 0;
	
	for (int i = 0; i < linklist->length; i++) 
		printf("%d\\t%s\\t\\n", node->date.id, node->date.name);
        node = node->next;
	

顺序表查空

int IsLinkListEmpty(LinkList* linkList) 

	return linkList->length == 0 ? TRUE : FALSE;


顺序表的删除 

删除第i个结点及其数据元素

  1. 获取第i个结点,若该结点不是第一个结点,则获取第i - 1个结点
  2. 将第i -1个结点的后缀结点设为第i个结点的后缀结点
  3. 删除第i个结点,释放内存空间,记录并返回删除数据元素的值

情况1:当删除的是第一个元素

	if (pos == 1)
	
		node = linkList->next;
		if (node) 
			element = node->date;
			linkList->next = node->next;
			free(node);  //释放被删除的结点
			linkList->length--;
		
        return element;
	

 情况2:除第一个结点外

  1. 找到要删除的结点和他的前缀结点
  2. 要删除结点的next 赋值给前缀结点
  3. 释放要删除的结点
	Node* preNode; //前缀结点
	node = linkList->next;
	for (int i = 1; node && i < pos; i++)
	
		preNode = node;
		node = node->next;
	
	if (node)
	
		element = node->date;
		preNode->next = node->next;
		free(node);
		linkList->length--;
	
	return element;

完整代码

ElementType DeleteLinkListElement(LinkList* linkList, int pos)

	ElementType element;   //被删除的元素
	element.id = -999;     //赋一个不可能的值,来判断删除是否成功
	Node* node = NULL;

	if (pos == 1)
	
		node = linkList->next;
		if (node) 
			element = node->date;
			linkList->next = node->next;
			free(node);  //释放被删除的结点
			linkList->length--;
		
	

	Node* preNode; //前缀结点
	node = linkList->next;
	for (int i = 1; node && i < pos; i++)
	
		preNode = node;
		node = node->next;
	
	if (node)
	
		element = node->date;
		preNode->next = node->next;
		free(node);
		linkList->length--;
	
	return element;


删除单链表整表

  1. 声明结点p 和 q
  2. 将第一个结点赋值给p
  3. 循环将下一个结点赋值给q,释放p,将q赋值给p

 

void CleatLinkList(LinkList* linkList)

	Node* node = linkList->next;
	Node* nextNode;
	while (node) 
		nextNode = node->next;  //先记录当前结点的下一个结点,以便释放当前结点的内存
		free(node);
		node = nextNode;
	
	linkList->next = NULL;
	linkList->length = 0;

 

 


 

以上是关于数据结构与算法—— * 链表--- 单链表 *的主要内容,如果未能解决你的问题,请参考以下文章

408数据结构与算法—单链表

408数据结构与算法—单链表

java数据结构与算法:java代码模拟带头节点单向链表的业务

数据结构与算法学习——单链表相关算法

数据结构与算法学习——单链表相关算法

[数据结构与算法] 链表的其他类型