数据结构学习第三课(线性表之链表)

第三课

1,有头单链表

1.1链表的概念

链表和顺序表都是线性表的一种,但是链表的每个数据的存储是不连续的;每个元素如何连接,需明白,在基本单位结构体中分为两种数据,分别是数据域和指针域,是由每个基本单位结构体的指针域指向下一个位置的地址,从而将它们连接起来,链表在内存空间中数据存储的位置的特点是分布离散的、随机的;它们就像串珠子一样一个接一个的线性结构;

基本框架事例:
typedef int Data;
typedef struct _Node
{
	Data dara;  //数据域
	struct _Node* next;//指向后继节点的指针
}Node,List;
创建一个链表(事例):
    List* createList()//创建一个链表
{
	List* list = calloc(1, sizeof(List));
	assert(list != NULL);
	list->next = NULL;
	list->dara = -1;//头结点里面的数据域不存储任何东西
	return list;
}
1.2头指针与头结点

头指针:指向链表第一个结点的指针,如果有头结点,那么头指针就是头结点的指针;

头结点:头结点是为了操作统一和方便而设立,即放在第一个元素的结点之前,数据域一般没有意义(也可以放链表长度);

1.3链表的分类

有头链表、无头链表、双向链表、双向循环链表;

1.4创建一个新结点
Node* createNode(Data data)
{
	Node* newNode = malloc(sizeof(Node));//创建一个结点
	assert(newNode != NULL);
	newNode->next = NULL;
	newNode->data = data;
	return newNode;
}
1.5尾插
例子:
void push_back(List* list, Data data)
{
	Node* newNode = createNode(data);//创建一个结点
	Node* curNode = list;
	while (curNode->next!=NULL)
	{
		curNode = curNode->next;
	}
	curNode->next = newNode;//连接到新结点
}
1.6头插
例子:
    void push_front(List* list, Data data)
{
	Node* newNode = createNode(data);
	newNode->next = list->next;
	list->next = newNode;
}
1.7指定位置插入
例子:
    void insert(List* list, Node* pos, Data data)
{
	Node* newNode = createNode(data);
	Node* curNode = list;
	while (curNode->next!=pos)
	{
		curNode = curNode->next;
	}
	newNode->next = pos;
	curNode->next = newNode;
}
1.8查找
例子:
Node* find(List* list, Data data)
{
	Node* curNode = list;
	while (curNode->next!=NULL)
	{
		curNode = curNode->next;
		if (data==curNode->data)
		{
			return curNode;
		}
	} 
	return NULL;
}
1.9判断为空
#include<stdbool.h>
bool empty(List* list)
{
	return list->next == NULL;
}
1.10展示
void show_list(List* list)
{
	Node* curNode = list->next;
	while (curNode!=NULL)
	{
		printf("%d ", curNode->data);
		curNode = curNode->next;
	}
	printf("\n");
}
1.11头删
例子:
void pop_front(List* list)
{
	if (empty(list))
	{
		return;
	}
	Node* delNode =list->next;//暂存
	list->next = delNode->next;
	free(delNode);
	delNode = NULL;
}
1.12尾删
例子:
void pop_back(List* list)
{
	if (empty(list))
	{
		return;
	}
	Node* curNode = list;
	while (curNode->next->next!=NULL)
	{
		curNode = curNode->next;
	}
	free(curNode->next);
	curNode->next = NULL;
}
1.13指定位置删除
例子:
void erase_val(List* list, Data data)
{
	if (empty(list))
	{
		return;
	}
	Node* curNode = list;
	while (curNode->next!=NULL)
	{
		if (curNode->next->data==data)
		{
			Node* delNode = curNode->next;
			curNode->next = delNode->next;
			free(delNode);
			return;
		}
		if (curNode->next->next!=NULL)
		{
			curNode = curNode->next;
		}
	}
}
1.14排序
void sort(List* list)
{
    //链表不为空且不止一个结点
	if (empty(list)&&list->next->next!=NULL)
		return;
	for (Node* i = list->next; i->next!=NULL ; i=i->next)
	{
		for (Node* curNode = list->next; curNode->next!= NULL; curNode = curNode->next)
		{
			if (curNode->data>curNode->next->data)
			{
				Data t = curNode->data;
				curNode->data=curNode->next->data;
				curNode->next->data = t;
			}
		}
	}
}
1.15清除
void clear(List* list)
{
	if (empty(list))
	{
		return;
	}
	while (list->next!=NULL)
	{
		pop_front(list);
	}
}
1.16销毁
void destory(List** list)
{
	clear(*list);
	free(*list);
	*list = NULL;
}
1.17反转
void reverse(List* list)
{
	if (empty(list))
	{
		return;
	}
	Node* curNode = list->next;//当前处理结点的位置
	Node* prevNode = NULL;//保存上一个结点的位置
	Node* nextNode = NULL;//保存下一个结点的位置;
	while (curNode!=NULL)
	{
		nextNode = curNode->next;
		curNode->next = prevNode;
		prevNode = curNode;
		curNode = nextNode;
	}
	list->next = prevNode;
}
1.18全选和缩放快捷键
全选:Ctrl+a;
缩放(打开缩放):Ctrl+m+m
上一篇:约瑟夫环(杀人游戏)


下一篇:数据结构之LinkedList | 让我们一块来学习数据结构