您的位置:首页 > 编程语言 > C语言/C++

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

2017-06-08 20:30 393 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 C语言
相关文章推荐