C实现链表一般接口函数(插入,删除,排序,等等)

本文详细介绍了一个简单的链表实现,包括链表的初始化、创建、遍历、插入、删除及排序等核心功能,并通过一个完整的C语言程序展示了这些功能的具体应用。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <errno.h>
#include <stdbool.h>

//内存分配错误信息宏
#define MALLOC_ERR(info) ({perror(info);exit(0);})

//定义一个节点结构体
typedef struct node
{
	int data;				//数据域
	struct node *pNext;		//指针域(指向下一个节点)
}NODE,*pNODE;

//功能:链表初始化
//输入:NULL
//返回:头结点
pNODE init_list(void){
	pNODE pHead = NULL;
	
	pHead = (pNODE)malloc(sizeof(NODE));
	
	if(NULL == pHead)
		MALLOC_ERR("init_list");
	pHead->pNext = NULL;		//每一次申请一个节点 就去初始化节点(数据域和指针域)
								//但是头结点无数据域
	return pHead;
}
//功能:创建链表
//输入:pHead:		头结点
//		list_len:	要创建链表的长度(去掉头结点和尾节点)
//返回:NULL
void creat_list(pNODE pHead,int list_len){
	int i = 0;
	pNODE pTemp = pHead;	//参考节点
	pNODE pNew = NULL;		//定义新节点
	
	for(i=0;i<list_len;i++){
		pNew = (pNODE)malloc(sizeof(NODE));	
		if(NULL == pNew)
			MALLOC_ERR("creat_list");
		pNew->data = list_len-i;	//每一次申请一个节点 就去初始化节点(数据域和指针域)
		pNew->pNext = NULL;			//为数据域赋值list_len到1,为后面做测试用。
		
		pTemp->pNext = pNew;		//将新节点加载到前一个节点后面
		pTemp = pNew;				//参考节点向后指针向后移动一位
	}
	//printf("CREAT LIST SUCCESS!\n");
}
//功能:获取链表长度
//输入:pHead:		头结点
//返回:list_len:	链表长度(去掉头结点和尾节点)
int get_list_len(pNODE pHead){
	int list_len = 0;
	int i = 0;
	pNODE pTemp = pHead->pNext;
	
	while(NULL != pTemp){
		pTemp = pTemp->pNext;
		list_len++;
	}
	return list_len;
}
//功能:遍历链表
//输入:pHead:		头结点
//返回:NULL
void traverse_list(pNODE pHead){
	int i = 0;
	pNODE pTemp = pHead;
	
	for(i=0;i<get_list_len(pHead);i++){
		printf("NODE[%d] = %d\n",i+1,pTemp->pNext->data);//打印出链表中的数据域(做测试用)
		pTemp = pTemp->pNext;
	}
}
//功能:插入链表节点
//输入:pHead:		 头结点
//		insert_pos: 插入的位置
//		insert_data:插入的数据
//返回:NULL
void insert_list(pNODE pHead,int insert_pos,int insert_data){
	int i = 0;
	pNODE pTemp = pHead;
	pNODE pInsert = NULL;
	
	if(insert_pos > get_list_len(pHead)){//如果插入位置超出链表范围 退出进程
		printf("error:INSERT OVER LIST LENGTH!\n");
		exit(0);
	}
	pInsert = (pNODE)malloc(sizeof(NODE));
	if(NULL == pInsert)
			MALLOC_ERR("insert_list");
	pInsert->data = insert_data;	//初始化插入节点的数据域和指针域
	pInsert->pNext = NULL;
	
	for(i=0;i<insert_pos;i++)		//将指针指向定位到要插入的位置
		pTemp = pTemp->pNext;
	pInsert->pNext = pTemp->pNext;	//插入节点的下一个为原来指针指向的下一个
	pTemp->pNext = pInsert;			//原来指针指向的下一个为新插入的节点
	//printf("INSERT LIST SUCCESS!\n");
}
//功能:删除链表节点
//输入:pHead:		 头结点
//		insert_pos: 要删除的位置
//返回:NULL
void delete_list(pNODE pHead,int delete_pos){
	int i = 0;
	pNODE pTemp = pHead;
	pNODE pDelete/* = pHead->pNext*/;
	
	if(delete_pos > get_list_len(pHead)){//如果删除的位置超出链表范围 退出进程
		printf("error:DELETE OVER LIST LENGTH!\n");
		exit(0);
	}
	for(i=0;i<delete_pos;i++)			//将指针指向定位到要删除的位置
		pTemp = pTemp->pNext;
	pDelete = pTemp->pNext;
	
	pTemp->pNext = pDelete->pNext;
	
	free(pDelete);						//释放被删除节点的内存
	//printf("DELETE LIST SUCCESS!\n");
}
//功能:排序链表节点
//输入:pHead:		 头结点
//返回:NULL
void sort_list(pNODE pHead){
	pNODE i_pTemp = pHead;
	pNODE j_pTemp = pHead->pNext;
	pNODE Temp;		//定义参考节点
	int i = 0,j = 0;
	
	//请画图理解下面的程序(升序排列)
	for(i=0;i<get_list_len(pHead);i++){
		for(j=1;j<get_list_len(pHead)-i;j++){
			if(i_pTemp->pNext->data > j_pTemp->pNext->data){//如果前面数据大于后面数据
				Temp = j_pTemp->pNext->pNext;		//将指针指向调换
				i_pTemp->pNext = j_pTemp->pNext;
				j_pTemp->pNext->pNext = j_pTemp;
				j_pTemp->pNext = Temp;
				j_pTemp = i_pTemp->pNext;//j_pTemp复位
										 //此时j_pTemp位置已被交换位置
										 //所以 要复位j_pTemp永远在i_pTemp后面
			}
			i_pTemp = i_pTemp->pNext;	//向下比较 指针指向移到下一个节点
			j_pTemp = j_pTemp->pNext;
		}
		i_pTemp = pHead;				//指向复位(冒泡排序法)
		j_pTemp = pHead->pNext;
	}
}
//主函数
int main(void){
	pNODE pHead = NULL;
	int list_len = 0;
	
	pHead = init_list();				//创建头结点
	creat_list(pHead,6);				//创建链表
	list_len = get_list_len(pHead);		//获取链表长度
	printf("=== == =遍历链表测试 = == ===\n");
	printf("list_len = %d\n",list_len);	//链表长度测试
	traverse_list(pHead);				//遍历链表
	printf("=== == =插入节点测试 = == ===\n");
	insert_list(pHead,3,520);			//插入节点(插入到第三个节点后 值为520)
	traverse_list(pHead);				//遍历链表测试插入节点
	printf("=== == =删除节点测试 = == ===\n");
	delete_list(pHead,3);				//删除节点(三次第三个节点 里面的值是520)
	traverse_list(pHead);				//遍历链表测试删除节点
	printf("=== == =链表排序测试 = == ===\n");
	sort_list(pHead);					//链表升序排列
	traverse_list(pHead);				//遍历链表测试链表排序
	
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值