博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c 语言 单链表的所有操作
阅读量:3966 次
发布时间:2019-05-24

本文共 15783 字,大约阅读时间需要 52 分钟。

c 语言 单链表的所有操作

单链表的定义:

//静态链表typedef struct _LinkList {	int data;//数据	struct _LinkList* next;//指向下一个节点	int length;//计算链表的长度;}LinkList;//ptrLinkList 是 LinkList指针类型;typedef LinkList* ptrLinkList;

ptrLinkList 是一个LinkList 结构体的指针类型;

注意: 注释中头结点不是链表的第一个节点,是第一个节点之前的节点,是哨兵,没有实际的作用.

文章目录

//这原本是一个替别人写的作业,可是价钱没有谈拢,就只能改一下,做成一篇博客了,要不然太亏了😂😂😂

一.链表头结点的初始化

/**函数作用:初始化静态链表头结点* *函数参数:head 是一个LinkList 二级指针 *         //为什么用二级指针 函数传参时指针降级 *         //需要动态内存分配head一级指针  改变一级指针指向的地址**函数返回值: head 动态内存分配成功 返回1; 否则返回0;*/int initLinkList(LinkList** head) {	if (!head) return 0;	*head = (LinkList*)malloc(sizeof(LinkList));		if (!*head) return 0;	(*head)->next = NULL;	(*head)->data = -1;	(*head)->length = 0;	return 1;}

二.链表的后插法

/**函数作用:在静态链表尾追加节点(后插法)**函数参数: head 是静态链表的头结点*          data 是待插入静态链表节点的数据**函数返回值:插入节点数据成功返回1;否则返回0;*/int pushBackLinkList(ptrLinkList head,int data) {
if (!head) return 0; ++head->length; ptrLinkList temp = NULL; temp = (LinkList*)malloc(sizeof(LinkList)); //动态内存分配失败; if (!temp) return 0; temp->data = data; while (head->next) {
head = head->next; } head->next = temp; temp->next = NULL; return 1;}

三.链表的前插法

/**函数作用:在静态链表第一个节点追加节点(前插法)**函数参数: head 是静态链表前的头结点*          data 是待插入静态链表节点的数据**函数返回值:插入节点数据成功返回1;否则返回0;*/if (!head) return 0;	++head->length;	ptrLinkList temp = NULL;	temp = (LinkList*)malloc(sizeof(LinkList));	//动态内存分配失败;	if (!temp) return 0;	temp->data = data;	temp -> next =head->next;	head->next = temp;	return 1;}

四.链表的打印

/**函数作用:打印全部的静态链表节点数据**函数参数: head 是静态链表的头结点**函数返回值:打印节点数据成功返回1;否则返回0;*/int printLinkListData(ptrLinkList head){
//这个head 指向了空,这个链表为空 if (!head || !head->next) return 0; printf("\n"); //插入排序(升序) //insertSortLinkList(head); ptrLinkList temp = head->next; while (temp) {
printf("%d\t", temp->data); temp = temp->next; } printf("\n"); return 1;}

五.链表的查找

/**函数作用:查找静态链表节点中数据是否有target**函数参数: head 是静态链表的头结点*        target 是需要查询的数据**函数返回值:找到target数据返回节点地址,否则返回NULL;*/ptrLinkList findLinkListData(ptrLinkList head, int target) {
if (!head || !head->next) return 0; ptrLinkList temp = head->next; while (temp) {
if (temp->data == target) {
return temp; } temp = temp->next; } return NULL;}

六.链表的删除节点中的数据与指定数据相同的节点

/**函数作用:节点数据与target相同删除一个节点**函数参数: head 是静态链表的头结点*          target 是需要删除的节点数据**函数返回值:找到target与节点数据相同的并删除节点返回1,否则返回0;*/int deleteLinkListNode(ptrLinkList head,int target) {
if (!head || !(head->next)) return 0; //删除的节点 ptrLinkList appointNode = head->next; //删除节点的上一个节点 ptrLinkList previousNode = head; while (appointNode) {
if (appointNode->data == target) break; previousNode = appointNode; appointNode = appointNode->next; } if (appointNode) {
previousNode->next = appointNode -> next; free(appointNode); --head->length; return 1; } return 0;}

七.删除指定节点

/**函数作用:删除target节点**函数参数: head 是静态链表的头结点*          target 是一个链表节点地址**函数返回值:找到target与节点地址相同的并删除节点返回1,否则返回0;*/int deleteLinkListNode(ptrLinkList head, ptrLinkList target) {
if (!head || !(head->next)) return 0; ptrLinkList appointNode = head->next; //删除节点的上一个节点 ptrLinkList previousNode = head; while (appointNode) {
if (appointNode == target) {
ptrLinkList tmp = appointNode; previousNode->next = appointNode->next; appointNode = appointNode->next; free(tmp); --head->length; break; } previousNode = appointNode; appointNode = appointNode->next; } return 0;}

八. 使用插入排序进行升序排列链表

/**函数作用: 使用插入排序进行升序**函数参数: head 是静态链表的头结点**函数返回值: 无*/void insertSortLinkList(ptrLinkList head) {
//当前链表的头结点 if (!head || !(head->next) || !(head -> next -> next))return; //p 指向的是这个链表的第一个结点 ptrLinkList p = head->next; //pend 指向的是这个链表的第二个节点 ptrLinkList pend = p->next; while (p) {
//tempHead 先指向 第一个节点 (待插入位置) ptrLinkList tempHead = head -> next; //preNode 先指向 头结点(哨兵) preNode 为插入位置的上一个节点 ptrLinkList preNode = head; //从第一个节点 开始 找到前一个节点的数据比下一个节点数据大的 //外循环的第二个循环开始就不会再回到第一个节点比较了 while (pend && (p->data <= pend->data)) {
p = p->next; pend = pend->next; } if (pend) {
//从第一个节点开始 找 比pend节点中的数据大的插入 while ( tempHead->data <= pend->data) {
preNode = tempHead; tempHead = tempHead->next; } //保存 pend 指向的下一个节点 ptrLinkList t = pend->next; //前一个节点的next 指向 pend (插入) preNode->next = pend; //pend 的 next 指向 从第一个节点开始第一个比pend节点中的数据大的 pend->next = tempHead; //pend = 它先前保存的下一个节点 pend = t; //先前p 的next 是指向 pend的 pend更新了 p 的 next 指向的也更新 //p 永远 是 pend 的前一个节点 p -> next = pend; } else {
break; } }}

九,删除重复项

/**函数作用:删除链表节点的重复项**函数参数: head 是静态链表的头结点**函数返回值:删除成功返回1,否则返回0;*/int deleteRepetitionNode(ptrLinkList head) {
if (!head || !(head->next) || !(head->next->next)) return 0; ptrLinkList slowPtr = head->next; ptrLinkList quickPtr = slowPtr->next; while (quickPtr) {
if (quickPtr->data == slowPtr->data) {
ptrLinkList temp = quickPtr; quickPtr = quickPtr->next; deleteLinkListNode(head, temp); } else {
slowPtr = slowPtr->next; quickPtr = quickPtr->next; } } return 1;}

十.反转链表

/**函数作用:反转链表(使用递归和后插法)**函数参数 : head 是静态链表的第一个节点**函数返回值 : 反转成功返回新的第一个节点, 否则返回NULL;*/ptrLinkList reversalLinkList(ptrLinkList head) {
if (!head || !(head->next)) return head; ptrLinkList ret = reversalLinkList(head->next); ptrLinkList temp = ret; while (temp ->next) {
temp = temp->next; } temp->next = head; head->next = NULL; return ret;}

十一.链表的二个有序的链表合并成一个有序的链表

/**函数作用: 将二个有序的链表合并成一个有序的链表**函数参数:head1 第一个链表的第一个节点*         head2 第二个链表的第一个节点**函数返回值: 返回合并二个链表后的头结点*/ptrLinkList mergerSortLinkList(ptrLinkList head1,ptrLinkList head2) {
if (!head1 && !head2) return NULL; if (!head1) return head2; if (!head2) return head1; ptrLinkList pStart = NULL; initLinkList(&pStart); ptrLinkList temp = pStart; while (head1 && head2) {
while (temp->next) temp = temp->next; ptrLinkList t = NULL; if (head1->data <= head2->data) {
t = head1->next; head1->next = NULL; temp->next = head1; head1 = t; } else {
t = head2->next; head2->next = NULL; temp->next = head2; head2 = t; } } while (temp->next) temp = temp->next; if (!head1) {
temp->next = head2; } if (!head2) {
temp->next = head1; } return pStart;}

十二.请除链表全部节点

**函数作用:删除链表的全部节点**函数参数 : head 是静态链表的头节点**函数返回值 : 删除成功返回新的第一个节点, 否则返回NULL;*/int deleteLinkList(ptrLinkList head) {
if (!head) return 0; ptrLinkList temp = head; while (temp) {
head = head->next; free(temp); temp = head; } return 0;}

最后是我便于复制粘贴的代码可忽略

#include 
#include
#include
#include
//静态链表typedef struct _LinkList {
int data;//数据 struct _LinkList* next;//指向下一个节点 int length;//每增加一个节点++;}LinkList;//ptrLinkList 是 LinkList指针类型;typedef LinkList* ptrLinkList;/**函数作用:初始化静态链表头结点* *函数参数:head 是一个LinkList 二级指针 * //为什么用二级指针 函数传参时指针降级 * //需要动态内存分配head一级指针 改变一级指针指向的地址**函数返回值: head 动态内存分配成功 返回1; 否则返回0;*/int initLinkList(LinkList** head);/**函数作用:在静态链表尾追加节点(后插法)**函数参数: head 是静态链表的头结点* data 是待插入静态链表节点的数据**函数返回值:插入节点数据成功返回1;否则返回0;*/int pushBackLinkList(ptrLinkList head, int data);/**函数作用:在静态链表第一个节点前追加节点(前插法)**函数参数: head 是静态链表的头结点* data 是待插入静态链表节点的数据**函数返回值:插入节点数据成功返回1;否则返回0;*/int pushFrontLinkList(ptrLinkList head, int data);/**函数作用:打印全部的静态链表节点数据**函数参数: head 是静态链表的头结点**函数返回值:打印节点数据成功返回1;否则返回0;*/int printLinkListData(ptrLinkList head);/**函数作用:返回静态链表的节点数**函数参数: head 是静态链表的头结点**函数返回值:返回节点的个数*/int lengthLinkList(ptrLinkList head);/**函数作用:查找静态链表节点中数据是否有target**函数参数: head 是静态链表的头结点* target 是需要查询的数据**函数返回值:找到target数据返回节点地址,否则返回NULL;*/ptrLinkList findLinkListData(ptrLinkList head,int target);/**函数作用:节点数据与target相同删除一个节点**函数参数: head 是静态链表的头结点* target 是需要删除的节点数据**函数返回值:找到target与节点数据相同的并删除节点返回1,否则返回0;*/int deleteLinkListNode(ptrLinkList head, int target);/**函数作用:删除target节点**函数参数: head 是静态链表的头结点* target 是一个链表节点地址**函数返回值:找到target与节点地址相同的并删除节点返回1,否则返回0;*/int deleteLinkListNode(ptrLinkList head, ptrLinkList target);/**函数作用:删除与target数据相同的节点数据的所有节点;**函数参数: head 是静态链表的头结点* target 是一个链表节点**函数返回值:找到target与节点数据相同的并删除节点返回1,否则返回0;*///int deleteLinkListNodes(ptrLinkList head,int target);/**函数作用: 使用插入排序进行升序**函数参数: head 是静态链表的头结点**函数返回值: 无*/static void insertSortLinkList(ptrLinkList head);/**函数作用:删除链表节点的重复项**函数参数: head 是静态链表的头结点**函数返回值:删除成功返回1,否则返回0;*/int deleteRepetitionNode(ptrLinkList head);/**函数作用:反转链表(使用递归和后插法)**函数参数 : head 是静态链表的第一个节点**函数返回值 : 反转成功返回新的第一个节点, 否则返回NULL;*/ptrLinkList reversalLinkList(ptrLinkList head);/**函数作用: 将二个有序的链表合并成一个有序的链表**函数参数:head1 第一个链表的第一个节点* head2 第二个链表的第一个节点**函数返回值: 返回合并二个链表后的头结点*/ptrLinkList mergerSortLinkList(ptrLinkList head1,ptrLinkList head2);/**函数作用:删除链表的全部节点**函数参数 : head 是静态链表的头节点**函数返回值 : 删除成功返回新的第一个节点, 否则返回NULL;*/int deleteLinkList(ptrLinkList head);int main(void) {
//头结点head 和 head1 不存数据 哨兵 ptrLinkList head = NULL; ptrLinkList head1 = NULL; ptrLinkList mergerHead = NULL; //需要删除的元素值 int element; //链表长度; int length; //需要插入节点的个数 int n = 0; initLinkList(&head); initLinkList(&head1); printf("pleass input link list node amount:"); scanf_s("%d", &n); //设置随机种子 如果不设置 rand() 生成的数据是伪随机数 srand((unsigned int)time(0)); for (int i = 0; i < n; i++) {
//rand() 随机数据 //在静态链表尾追加一个节点 ,这个节点的数据 就是 rand()生成的数据 pushFrontLinkList(head, n -i); pushBackLinkList(head1, rand() % 10); } printf("\n"); //打印全部的静态链表节点数据 printf("print link list head :\n"); printLinkListData(head); printf("print link list head1 :\n"); printLinkListData(head1); /*length = lengthLinkList(head); printf("\n"); printf("link list length:%d", length)*/; /*printf("after Link List head that reversal:\n"); head ->next =reversalLinkList(head->next);*/ printf("after tow Link List merger:\n"); mergerHead = mergerSortLinkList(head->next, head1->next); //deleteRepetitionNode(head); printLinkListData(mergerHead); printf("pleass input data that you need remove :"); scanf_s("%d", &element); deleteLinkListNode(mergerHead, element); printLinkListData(mergerHead); /*length = lengthLinkList(head); printf("link list length:%d", length);*/ printf("\n"); printf("delete all link list\n"); deleteLinkList(mergerHead); return 0;}int initLinkList(LinkList** head) {
if (!head) return 0; *head = (LinkList*)malloc(sizeof(LinkList)); if (!*head) return 0; (*head)->next = NULL; (*head)->data = -1; (*head)->length = 0; return 1;}int pushBackLinkList(ptrLinkList head,int data) {
if (!head) return 0; ++head->length; ptrLinkList temp = NULL; temp = (LinkList*)malloc(sizeof(LinkList)); //动态内存分配失败; if (!temp) return 0; temp->data = data; while (head->next) {
head = head->next; } head->next = temp; temp->next = NULL; return 1;}int pushFrontLinkList(ptrLinkList head, int data) {
if (!head) return 0; ++head->length; ptrLinkList temp = NULL; temp = (LinkList*)malloc(sizeof(LinkList)); //动态内存分配失败; if (!temp) return 0; temp->data = data; temp -> next =head->next; head->next = temp; return 1;}int printLinkListData(ptrLinkList head){
//这个head 指向了空,这个链表为空 if (!head || !head->next) return 0; printf("\n"); //插入排序(升序) //insertSortLinkList(head); ptrLinkList temp = head->next; while (temp) {
printf("%d\t", temp->data); temp = temp->next; } printf("\n"); return 1;}int lengthLinkList(ptrLinkList head) {
if (!head || !head -> next) return 0; return head->length;}ptrLinkList findLinkListData(ptrLinkList head, int target) {
if (!head || !head->next) return 0; ptrLinkList temp = head->next; while (temp) {
if (temp->data == target) {
return temp; } temp = temp->next; } return NULL;}void insertSortLinkList(ptrLinkList head) {
//当前链表的头结点 if (!head || !(head->next) || !(head -> next -> next))return; //p 指向的是这个链表的第一个结点 ptrLinkList p = head->next; //pend 指向的是这个链表的第二个节点 ptrLinkList pend = p->next; while (p) {
//tempHead 先指向 第一个节点 (待插入位置) ptrLinkList tempHead = head -> next; //preNode 先指向 头结点(哨兵) preNode 为插入位置的上一个节点 ptrLinkList preNode = head; //从第一个节点 开始 找到前一个节点的数据比下一个节点数据大的 //外循环的第二个循环开始就不会再回到第一个节点比较了 while (pend && (p->data <= pend->data)) {
p = p->next; pend = pend->next; } if (pend) {
//从第一个节点开始 找 比pend节点中的数据大的插入 while ( tempHead->data <= pend->data) {
preNode = tempHead; tempHead = tempHead->next; } //保存 pend 指向的下一个节点 ptrLinkList t = pend->next; //前一个节点的next 指向 pend (插入) preNode->next = pend; //pend 的 next 指向 从第一个节点开始第一个比pend节点中的数据大的 pend->next = tempHead; //pend = 它先前保存的下一个节点 pend = t; //先前p 的next 是指向 pend的 pend更新了 p 的 next 指向的也更新 //p 永远 是 pend 的前一个节点 p -> next = pend; } else {
break; } }}int deleteLinkListNode(ptrLinkList head,int target) {
if (!head || !(head->next)) return 0; //删除的节点 ptrLinkList appointNode = head->next; //删除节点的上一个节点 ptrLinkList previousNode = head; while (appointNode) {
if (appointNode->data == target) break; previousNode = appointNode; appointNode = appointNode->next; } if (appointNode) {
previousNode->next = appointNode -> next; free(appointNode); --head->length; return 1; } return 0;}int deleteRepetitionNode(ptrLinkList head) {
if (!head || !(head->next) || !(head->next->next)) return 0; ptrLinkList slowPtr = head->next; ptrLinkList quickPtr = slowPtr->next; while (quickPtr) {
if (quickPtr->data == slowPtr->data) {
ptrLinkList temp = quickPtr; quickPtr = quickPtr->next; deleteLinkListNode(head, temp); } else {
slowPtr = slowPtr->next; quickPtr = quickPtr->next; } } return 1;} int deleteLinkListNode(ptrLinkList head, ptrLinkList target) {
if (!head || !(head->next)) return 0; ptrLinkList appointNode = head->next; //删除节点的上一个节点 ptrLinkList previousNode = head; while (appointNode) {
if (appointNode == target) {
ptrLinkList tmp = appointNode; previousNode->next = appointNode->next; appointNode = appointNode->next; free(tmp); --head->length; break; } previousNode = appointNode; appointNode = appointNode->next; } return 0;}ptrLinkList reversalLinkList(ptrLinkList head) {
if (!head || !(head->next)) return head; ptrLinkList ret = reversalLinkList(head->next); ptrLinkList temp = ret; while (temp ->next) {
temp = temp->next; } temp->next = head; head->next = NULL; return ret;}ptrLinkList mergerSortLinkList(ptrLinkList head1,ptrLinkList head2) {
if (!head1 && !head2) return NULL; if (!head1) return head2; if (!head2) return head1; ptrLinkList pStart = NULL; initLinkList(&pStart); ptrLinkList temp = pStart; while (head1 && head2) {
while (temp->next) temp = temp->next; ptrLinkList t = NULL; if (head1->data <= head2->data) {
t = head1->next; head1->next = NULL; temp->next = head1; head1 = t; } else {
t = head2->next; head2->next = NULL; temp->next = head2; head2 = t; } } while (temp->next) temp = temp->next; if (!head1) {
temp->next = head2; } if (!head2) {
temp->next = head1; } return pStart;}int deleteLinkList(ptrLinkList head) {
if (!head) return 0; ptrLinkList temp = head; while (temp) {
head = head->next; free(temp); temp = head; } return 0;}

next;

}

temp->next = head;head->next = NULL;return ret;

}

ptrLinkList mergerSortLinkList(ptrLinkList head1,ptrLinkList head2) {

if (!head1 && !head2) return NULL;
if (!head1) return head2;
if (!head2) return head1;

ptrLinkList pStart = NULL;initLinkList(&pStart);ptrLinkList temp = pStart;while (head1 && head2) {	while (temp->next) temp = temp->next;	ptrLinkList t = NULL;	if (head1->data <= head2->data) {		t = head1->next;		head1->next = NULL;		temp->next = head1;				head1 = t;	}	else {		t = head2->next;		head2->next = NULL;		temp->next = head2;		head2 = t;	}}while (temp->next) temp = temp->next;if (!head1) {	temp->next = head2;}if (!head2) {	temp->next = head1;}return pStart;

}

int deleteLinkList(ptrLinkList head) {

if (!head) return 0;

ptrLinkList temp = head;while (temp) {	head = head->next;	free(temp);	temp = head;}return 0;

}

转载地址:http://xbyki.baihongyu.com/

你可能感兴趣的文章
Android音频系统之AudioPolicyService
查看>>
Android系统Root与静默安装
查看>>
Android Property实现介绍
查看>>
Android SystemProperties设置/取得系统属性的用法总结
查看>>
Android 休眠 FLAG_KEEP_SCREEN_ON
查看>>
Android添加onKeyLongPress事件
查看>>
Android使用Contact数据模型来批量插入联系人
查看>>
使用微信api将内容分享给好友,或者发送到朋友圈
查看>>
百度地图SDK坐标传入导航sdk 示例
查看>>
免费的sip账号
查看>>
android开发中输入法的弹出和隐藏
查看>>
Android 如何在自定义界面上启用输入法 (How to enable inputmethod for the custom UI)
查看>>
Android MediaCodec小结
查看>>
详解YUV数据格式
查看>>
YUV格式说明
查看>>
MediaCodec and Camera: colorspaces don't match
查看>>
How to use Android MediaCodec encode Camera data(YUV420sp)
查看>>
android adb 读写模式 挂载文件系统
查看>>
onTouchEvent方法的使用
查看>>
Android详细解释键盘和鼠标事件
查看>>