IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 3.2、离散存储【链表】 -> 正文阅读

[网络协议]3.2、离散存储【链表】

你要从自己开始,先检讨自己。

3.2、 离散存储【链表】

? 定义:

? ?????????n个节点离散分配

? ?????????彼此通过指针相连

? ?????????每个节点只有一个前驱节点,每个节点只有一个后继节点

? ?????????首节点没有前驱节点,尾节点没有后继节点

? 专业术语:

? ?????????首节点:

? ??????????????????第一个有效节点

? ?????????尾节点:

? ??????????????????最后一个有效节点

? ?????????头结点:

? ??????????????????头结点的数据类型和首节点类型一样

? ??????????????????第一个有效节点之前的那个节点

? ??????????????????头节点并不存放有效数据

? ??????????????????加头结点的目的主要是为了方便对链表的操作

? ?????????头指针:

? ??????????????????指向头结点的指针变量

? ?????????尾指针:

? ??????????????????指向尾节点的指针变量

?????????问题:
? ??????????????????如果希望通过一个函数来对链表进行处理,我们至少需要接收链表的哪些参数?

? ???????????????????????????只需要一个参数:头指针

? ???????????????????????????因为我们通过头指针可以推算出链表的其他所有参数

?????????数据结构:

# include <stdio.h>

typedef struct Node
{
	int data; // 数据域 
	struct Node * pNext; // 指针域 
}NODE, *PNODE; // NODE 等价于 struct Node, PNODE 等价于 struct Node * 


?????????分类:

? ??????????????????单链表

? ??????????????????双链表

? ??????????????????循环链表

? ??????????????????非循环链表

?
? ?????????算法:

? ??????????????????狭义的算法是与数据的存储方式密切相关

? ??????????????????广义的算法是与数据的存储方式无关

? ?????????泛型:

? ??????????????????利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的

?

? ?????????链表的优缺点:

? ??????????????????优点:

? ??????????????????插入和删除速度快(只需改变指针指向即可);

? ??????????????????没有空间限制,只与内存空间大小有关;

? ??????????????????内存利用率变高;

? ?????????缺点:

? ??????????????????占用额外的空间存储指针,比较浪费空间,不连续存储,malloc函数开辟空间碎片比较多;

? ??????????????????查找速度比较慢,因为在查找时,需要循环链表。

示例代码:

# include <stdio.h>
# include <stdlib.h>
// # include <malloc.h>
typedef struct Node
{
	int data; // 数据域 
	struct Node * pNext; // 指针域 
}NODE, *PNODE; // NODE 等价于 struct Node, PNODE 等价于 struct Node * 

// 函数申明
PNODE create_list(void); //创建链表 
void traverse_list(PNODE pHead); // 遍历链表 
bool is_empty(PNODE pHead); // 判断链表是否为空 
int length_list(PNODE pHead); // 求链表的长度 
// 在pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值val,
// 并且pos的值从1开始 
bool insert_list(PNODE pHead, int pos, int val); 
bool delete_list(PNODE pHead, int pos, int *pVal);
void sort_list(PNODE pHead); // 对链表进行排序 
 
int main(void)
{
	PNODE pHead = NULL; 
	
	pHead = create_list();
	
	int len = length_list(pHead); 
	printf("链表的长度为:%d\n",len);
	traverse_list(pHead);
	
	sort_list(pHead);
	
	printf("排序后:\n");
	traverse_list(pHead);
	
	
	insert_list(pHead, 6, 66); // 在链表第6个元素之前插入元素 66 
	traverse_list(pHead);
	
	int val; // 保存被删除的元素 
	if (delete_list(pHead, 6, &val)) {
		printf("元素 %d删除成功!\n",val); 
	}else {
		printf("被删除的元素不存在!\n");
	}
	traverse_list(pHead);
	return 0; 
} 

PNODE create_list(void)
{
	// 创建头节点
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	PNODE pTail = pHead; //尾指针 
	pTail->pNext = NULL; 
	
	int len; // 链表长度 
	int i;
	int val; // 存放输入的节点的数据域 
	
	printf("请输入需要创建的链表的长度:len=");
	scanf("%d",&len);
	
	for(i = 0; i < len; i++)
	{
		printf("请输入第%d个值:",i+1);
		scanf("%d",&val);
		
		// 创建节点
		PNODE pNew = (PNODE)malloc(sizeof(NODE));
		
		pNew->data = val; // 将数据挂在新节点的数据域 
		
		// 将新节点插入到尾节点后面 
		pTail->pNext = pNew;
		pNew->pNext = NULL;
		pTail = pNew;

	}
	return pHead;
}


void traverse_list(PNODE pHead)
{
	// 刚开始 p 指向第一个有效节点 
	PNODE p = pHead->pNext;
	
	while(p != NULL)
	{
		printf("%d \t",p->data);
		p = p->pNext;
	}
	printf("\n"); 
	
	return;
}

bool is_empty(PNODE pHead)
{
	if(NULL == pHead->pNext)
	{
		return true;
	}
	return false;
	
}
int length_list(PNODE pHead)
{
	int length = 0;
	PNODE p = pHead->pNext;
	
	while(p != NULL)
	{
		length ++;
		p = p->pNext;
	}
	return length;
}


void sort_list(PNODE pHead)
{
	int i ,j;
	int len = length_list(pHead);
	
	int temp;
	PNODE p,q; 
	
	for(i = 0,p = pHead->pNext; i<len-1; i++, p = p->pNext)
	{
		for(j = i+1, q = p->pNext; j < len; j++,q = q->pNext)
		{
			if (p->data > q->data)
			{
				//交换 
				temp = p->data;
				p->data = q->data;
				q->data = temp;
			}
		}
		
	}
	
	// 去掉i,j写法 
//	for(p = pHead->pNext; p->pNext != NULL; p = p->pNext)
//	{
//		for( q = p->pNext; q != NULL;q = q->pNext)
//		{
//			if (p->data > q->data)
//			{
//				//交换 
//				temp = p->data;
//				p->data = q->data;
//				q->data = temp;
//			}
//		}	
//	}
	return;
}


// 在pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值val,
// 并且pos的值从1开始 
bool insert_list(PNODE pHead, int pos, int val)
{
	int i = 0;
	PNODE p = pHead;
	
	while (NULL != p && i < pos-1)
	{
		p = p->pNext;
		i++;
	}
	if (i > pos-1 || NULL == p)
	{
		return false;
	}
	
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	pNew->data = val;
	
	pNew->pNext = p->pNext;
	p->pNext = pNew;
	
	return true;	
}


bool delete_list(PNODE pHead, int pos, int *pVal)
{
	int i = 0;
	PNODE p = pHead;
	
	while (NULL != p && i < pos-1)
	{
		p = p->pNext;
		i++;
	}
	// 跳出循环,p指向的是第 pos-1个节点,即待删除节点的前一个节点 
	
	if(i > pos-1 || NULL == p->pNext)
		return false;
	
	
	PNODE q = p->pNext; // 保存要删除的节点
	
	*pVal = q->data;
	p->pNext = 	p->pNext->pNext;
	free(q);
	q = NULL;
	return true;
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:27:45  更:2022-01-03 16:29:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 9:30:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码