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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C语言单向链表的创建,增加,删除和打印,以及模块化设计 -> 正文阅读

[数据结构与算法]C语言单向链表的创建,增加,删除和打印,以及模块化设计

链表:一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次 序实现的。链表由一系列结点(链表中每一个元素称为 结点)组成,结点可以在运行时动态生成。每个结点包 括两个部分:一个是存储数据元素的数据域,另一个是 存储下一个结点地址的指针域。?

涉及链表的操作有很多,今天简单讲解一下单向链表的创建 增加 删除 打印。

首先声明一个结构体要有数据域和指针域,因为链表是非连续、非顺序的存储结构,需要用指针来找到下一个结点的位置。声明常用有两种方法:

/*第一种*/
struct Node
{
	int date;          //数据域
	struct Node * next;	 //指针域
};


/*第二种*/
typedef struct Node
{
	int date;          //数据域
	struct Node * next;	 //指针域
}Node;
  • 创建链表与结点
//创建链表 
struct Node * createList()    
{
	struct Node * headNode = (struct Node *)malloc(sizeof(struct Node));
	//headNode变成一个变量
	//变量使用前初始化
	headNode->next = NULL;
	tail=headNode;  //后面尾插会用到
	return headNode;
}; 
//创建结点 
struct Node * createNode(int date)
{
	struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
	newNode->date = date;
	newNode->next = NULL;
	return newNode;
}
  • 增加结点(头插法和尾插法)(ps:不要将头插和尾插混合使用)
  1. 头插法

思路:

插入的结点永远在头结点的后面,同时要保证让新结点先指向原来的头结点后一位,再让头结点记录新结点的位置,因为如果是先让头结点记录新结点的位置,那么,原来结点的位置信息就丢失了,这个链表就会中断,连不起来,结合图理解。

?代码:

//插入结点(头插法)
void insertNodebyHead(struct Node * headNode, int date)
{
	//创建新结点 
	struct Node * newNode = createNode(date); 
	
    /*位置不能交换*/
	newNode->next = headNode->next;
	headNode->next= newNode;
	 
} 

? ? ? ? 2.尾插法

思路:

将新的结点加在链表的尾端,我们知道结点的位置只能通过上一个结点来找到它,所以我们就要用一个tail指针来确定最后一个结点的位置。所以我们需要一开始声明一个tail指针。

代码:

//插入结点(尾插法) 
void insertNodebyTail(struct Node * headNode, int date)
{
	//创建新结点
	struct Node * newNode = createNode(date);
	
	tail->next = newNode;
	tail = newNode;
}
  • 删除结点

思路:

删除的话涉及查找,我们肯定是先找到,在删除,所以我们需要两个指针来遍历链表,一个在前,一个在后,后一位的指针负责查找,前一位的指针负责将删除后的链表仍然串起来。

代码:

//删除结点
void deleteNode(struct Node * headNode, int posDate)
{
	struct Node * posNode = headNode->next;
	struct Node * posNodefront = headNode;
	
	if (posNode == NULL)
	{
		printf("无法删除链表\n");
	}
	
	else
	{
		/*查找*/
        while (posNode->date != posDate)
		{
			posNodefront = posNode;
			posNode = posNodefront->next;
			
			if (posNode == NULL)
			{
				printf("未找到指定结点,无法删除\n");	
				return;
			} 
		}
		posNodefront->next = posNode->next;
		free(posNode);    //删除
	}
} 
  • 打印链表

思路:

另外声明一个指针从头结点下一位开始,检查每一个结点的情况,如果不为NULL,打印出数据,如果为NULL,则退出。

代码:

//打印链表
void printList(struct Node * headNode)
{
	struct Node * pMove = headNode->next;  
	
	while (pMove != NULL)
	{
		printf("%d ", pMove->date);
		pMove = pMove->next;   
	} 
	printf("\n");
} 

完整的代码:

/*动态创建一个链表 */
//创建链表
//创建结点
//插入结点(头插法和尾插法) 
//删除结点
//打印遍历链表 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node * tail = NULL;
struct Node
{
	int date;
	struct Node * next;	
};

//创建链表 
struct Node * createList()    
{
	struct Node * headNode = (struct Node *)malloc(sizeof(struct Node));
	//headNode变成一个变量
	//变量使用前初始化
	headNode->next = NULL;
	tail=headNode;
	return headNode;
}; 

//创建结点 
struct Node * createNode(int date)
{
	struct Node * newNode = (struct Node *)malloc(sizeof(struct Node));
	newNode->date = date;
	newNode->next = NULL;
	return newNode;
}

//插入结点(头插法)
void insertNodebyHead(struct Node * headNode, int date)
{
	//创建新结点 
	struct Node * newNode = createNode(date); 
	
	newNode->next = headNode->next;
	headNode->next= newNode;
	 
} 
//插入结点(尾插法) 
void insertNodebyTail(struct Node * headNode, int date)
{
	//创建新结点
	struct Node * newNode = createNode(date);
	
	tail->next = newNode;
	tail = newNode;
}



//删除结点
void deleteNode(struct Node * headNode, int posDate)
{
	struct Node * posNode = headNode->next;
	struct Node * posNodefront = headNode;
	
	if (posNode == NULL)
	{
		printf("无法删除链表\n");
	}
	
	else
	{
		while (posNode->date != posDate)
		{
			posNodefront = posNode;
			posNode = posNodefront->next;
			
			if (posNode == NULL)
			{
				printf("未找到指定结点,无法删除\n");	
				return;
			} 
		}
		posNodefront->next = posNode->next;
		free(posNode);
	}
} 


//打印链表
void printList(struct Node * headNode)
{
	struct Node * pMove = headNode->next;  
	
	while (pMove != NULL)
	{
		printf("%d ", pMove->date);
		pMove = pMove->next;   
	} 
	printf("\n");
} 

int main(void)
{
	/*自己发挥*/
    
	return 0;
}

我是将链表的各个操作模块化了,这样看起来简洁,如果需要修改数据的话,只用改一下代码中的date就行了,同时单链表的一些其他操作也可以对上面的代码稍加修改即可。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:30:50  更:2021-12-06 15:32:48 
 
开发: 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年11日历 -2024/11/26 14:26:21-

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