#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实现链表一般接口函数(插入,删除,排序,等等)
最新推荐文章于 2024-10-11 19:57:20 发布
本文详细介绍了一个简单的链表实现,包括链表的初始化、创建、遍历、插入、删除及排序等核心功能,并通过一个完整的C语言程序展示了这些功能的具体应用。
2326

被折叠的 条评论
为什么被折叠?



