数据结构——离散存储【链表】

(第一次用markdown写笔记,有点排板就用了一个小时😢)

定义

n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点。

专业术语

  • 首节点:存放第一个有效数据的节点
  • 尾节点:存放最后一个有效数据的节点
  • 头节点:位于首节点之前的一个节点,头结点并不存放有效的数据,加头结点的目的主要是为了方便对链表的操作
  • 头指针:指向头结点的指针变量
  • 尾指针:指向尾节点的指针变量-

确定一个链表需要几个参数:只需要一个头指针参数,因为我们通过头指针可以推算出链表的其他所有信息


分类

单链表
双链表:每一个节点有两个指针域
循环链表:能通过一个节点找到其他所有节点
非循环链表


优缺点

  • 优点:空间没有限制,插入删除元素很快
  • 缺点:存取速度很慢。

代码如下

//2020.4.1/17:30
#include<iostream>

using namespace std;
typedef struct Node
{
	int data;//数据域
	struct Node* Next;//指针域  
}NODE, *PNODE;  
//从此之后 struct Node==NODE, struct Node*=PNODE;

//创建一个链表
PNODE create_list();
//遍历链表
void traverse_list(PNODE pHead);
//求链表长度
int length_list(PNODE pHead);
//在链表第pos的结点前插入数据为val的结点(pos>=1)
void insert_list(PNODE pHead, int pos, int val);
//删除链表第pos个结点,并把该结点数据赋予val输出
void delete_list(PNODE pHead, int pos, int* pval);
//排序(选择排序)
void sort_list(PNODE pHead);




int main()
{	
	PNODE pHead=create_list();	 
	traverse_list(pHead);
	cout << endl;
	insert_list(pHead, 3, 30);		
	traverse_list(pHead);
	cout << endl;
	int val;
	delete_list(pHead, 2, &val);
	cout << "被删除元素为" << val << endl;
    sort_list(pHead);
	traverse_list(pHead);
	return 0;
}

//

PNODE create_list()
{
	cout << "请输入链表有效结点的个数:";
	int len;
	cin >> len;
	if (len < 0)
	{
		cout << "请输入一个有效数据"; 
		exit(-1);
	}
	int val;//存放用户输入的结点的值
	//分配了一个不存放有效数据的头结点  并生成一个头指针指向它
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	//生成一个尾结点(相当于一个分身)
	PNODE pTail = pHead;
	pTail->Next = NULL;//尾结点的指针域为空
	for (int i = 0;i < len;i++)
	{
		cout << "请输入链表第" << i + 1 << "个结点的值:";
		cin >> val;
		PNODE pNew = (PNODE)malloc(sizeof(NODE));//生成新结点
		pNew->data = val;
		pTail->Next = pNew;
		pTail = pNew;
		pNew->Next = NULL;
	}
	return pHead;
}

//
void traverse_list(PNODE pHead)
{
	PNODE p = pHead->Next;
	while (p != NULL)
	{
		cout << p->data << ' ';
		p = p->Next;
	}
}
//
int length_list(PNODE pHead)
{	
	int len = 0;
	PNODE p = pHead->Next;
	while (p)
	{
		len++;
		p = p->Next;
	}
	return len;
}
//
void insert_list(PNODE pHead, int pos, int val)
{		
	if (pos < 0||(pos-1)>length_list(pHead)) //注意 要找到的是pos-1处的结点
	{
		cout << "输入pos错误";
		exit(-1);
	}
	PNODE p = pHead;
	for (int i = 0;i < pos - 1;i++)
	{
		p = p->Next;
	}
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	pNew->data = val;
	pNew->Next = p->Next;
	p->Next = pNew;
}
void delete_list(PNODE pHead, int pos, int* pval)
{
	if (pos < 0 || pos>length_list(pHead)) //注意 要找到的是pos-1处的结点||但是与插入不同 
	{
		cout << "输入pos错误";
		exit(-1);
	}
	PNODE p = pHead;
	for (int i = 0;i < pos - 1;i++)
	{
		p = p->Next;
	}
	PNODE q = p->Next;
	*pval = q->data;
	p->Next = q->Next;
	free(q);
}
//
void sort_list(PNODE pHead)
{
	int i, j, t;
	int len = length_list(pHead);
	PNODE p, q;

​	for (i = 0, p = pHead->Next; i < len - 1; ++i, p = p->Next)
​	{
​		for (j = i + 1, q = p->Next; j < len; ++j, q = q->Next)
​		{
​			if (p->data > q->data)  //类似于数组中的:  a[i] > a[j]
​			{
​				t = p->data;//类似于数组中的:  t = a[i];
​				p->data = q->data; //类似于数组中的:  a[i] = a[j];
​				q->data = t; //类似于数组中的:  a[j] = t;
​			}
​		}
​	}

​	return;
}

在最后,分享一下b站的郝斌老师,虽然我是一个菜🐶,​但他对我的影响非常大。

为什么我在20年还在看10年的视频..因为我对计算机的理解还停留在00年....

posted on 2020-04-01 22:50  The0Y  阅读(169)  评论(0编辑  收藏  举报

导航