【C语言】双链表的实现与冒泡排序
基于C语言,不做标题党,LInux下GCC通过编译,大致流程(底部附图,源码):
新建双链表(节点数自定义),对节点data域用随机数种子进行随机赋值,并对该链表进行冒泡排序。
后续其他排序陆续更新......
全局自定义函数如下:
//链表新建函数
LinkList *creat_LinkList()
//创建101个结点
void init_LinkList(LinkList *pHeader)
//链表data域赋值
void srand_LinkList(LinkList *pHeader)
//遍历
void foreach_LinkList(LinkList *pHeader)
//链表长度(包含头结点)
int size_LinkList(LinkList *pHeader)
//交换节点
void swap_LinkList(LinkList *pPre, LinkList *pCurrent)
//冒泡排序
void bubble_Sort(LinkList *pHeader, int size)
具体代码如下:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LinkList struct Node
#define MAX 100
//创建一个双链表结点
LinkList {
int data; //数据域
LinkList *pre; //前指针域
LinkList *next; //后指针域
};
//链表新建函数
LinkList *creat_LinkList() {
//新结点分配内存
LinkList *Node = (LinkList *) malloc(sizeof(LinkList *));
//判断内存分配成功失败
if (Node == NULL) {
printf("Memory distribution fail!\n");
return NULL;
}
//指针域初始化
Node->pre = NULL;
Node->next = NULL;
return Node;
}
//创建101个结点
void init_LinkList(LinkList *pHeader) {
//判空
if (pHeader == NULL)
return;
//首个带有数据的节点开辟空间
LinkList *pCurrent = (LinkList *) malloc(sizeof(LinkList *));
//pHeader与节点衔接
pHeader->next = pCurrent;
pCurrent->pre = pHeader;
//开辟节点个数控制(已存在head与第一个非空结点)
int num = MAX - 1; //(100 - 1 + 2)= 101
while (num) {
//pCurrent->next开辟空间(带有衔接next指针作用)
pCurrent->next = (LinkList *) malloc(sizeof(LinkList *));
//记录pCurrent,便于回滚
LinkList *pPre = pCurrent;
//双链表pre指针衔接
pCurrent->next->pre = pCurrent;
//回滚
pCurrent = pCurrent->next;
//计数
num--;
}
//置空末指针
pCurrent->next = NULL;
}
//链表data域赋值
void srand_LinkList(LinkList *pHeader) {
//判空
if (pHeader == NULL)
return;
//辅助指针
LinkList *pCurrent = pHeader->next;
//添加随机数种子
srand((unsigned) time(NULL));
//首个非空结点赋值
pCurrent->data = rand() % 500;
while (pCurrent) {
//随机赋值500以内整数值
pCurrent->data = rand() % 300;
//后移
pCurrent = pCurrent->next;
}
}
//遍历
void foreach_LinkList(LinkList *pHeader) {
//判空
if (pHeader == NULL)
return;
//辅助
LinkList *pCurrent = pHeader->next;
//向前遍历指针
LinkList *temp = pCurrent;
int num1 = 0;
//循环遍历
printf("———————————————————————————————————正遍历—————————————————————————————————————\n");
while (pCurrent) {
//print格式
//printf("%p\t",pCurrent);
printf("%d\t", pCurrent->data);
//向前遍历指针
temp = pCurrent;
num1++;
if (num1 % 10 == 0)
printf("\n");
//向后
pCurrent = pCurrent->next;
}
//向前遍历(尾节点开始)
pCurrent = temp;
int num2 = 0;
printf("————————————————————————————————————逆遍历————————————————————————————————————\n");
while (pCurrent) {
if (pCurrent == pHeader)
break;
printf("%d\t", pCurrent->data);
num2++;
if (num2 % 10 == 0)
printf("\n");
//向前
pCurrent = pCurrent->pre;
}
printf("————————————————————————————————————END————————————————————————————————————\n");
}
//链表长度(包含头结点)
int size_LinkList(LinkList *pHeader) {
//辅助
LinkList *pCurrent = pHeader;
//计数
int size = 0;
while (pCurrent) {
//向后
pCurrent = pCurrent->next;
size++;
}
return size;
}
//交换节点
void swap_LinkList(LinkList *pPre, LinkList *pCurrent) {
//指针转换 此处注意6个指针交换
//pPre与新前驱建立联系
pPre->pre->next = pCurrent;
pCurrent->pre = pPre->pre;
//pCurrent与新后驱建立联系
pCurrent->next->pre = pPre;
pPre->next = pCurrent->next;
//pPre与pCurrent互连
pPre->pre = pCurrent;
pCurrent->next = pPre;
}
/******************************排序开始******************************/
//冒泡排序
void bubble_Sort(LinkList *pHeader, int size) {
//判空
if (pHeader == NULL) {
return;
}
//初始化辅助指针
LinkList *pPre = pHeader;
LinkList *pCurrent = pHeader;
//循环次数
int num = size;
for (int i = 1; i < num; i++) {
//重置指针位置
pPre = pHeader->next;
pCurrent = pPre->next;
for (int j = 1; j < num - i; j++) {
if (pPre->data > pCurrent->data) {
//节点尾节点情况
if (pCurrent->next == NULL) {
pPre->next = pCurrent->next;
pCurrent->pre = pPre->pre;
pCurrent->next = pPre;
pPre->pre->next = pCurrent;
pPre->pre = pCurrent;
}
//非尾节点情况
else {
//交换节点
swap_LinkList(pPre, pCurrent);
//pCurrent指针后移到pPre前面
pCurrent = pPre->next;
}
}
//pPre->data > pCurrent->data非真情况下
else {
pPre = pPre->next;
pCurrent = pCurrent->next;
}
}
}
}
int main(void) {
//新建链表
LinkList *pHeader = creat_LinkList();
//链表初始化
init_LinkList(pHeader);
//链表data域赋值
srand_LinkList(pHeader);
//遍历
foreach_LinkList(pHeader);
//冒泡
bubble_Sort(pHeader, size_LinkList(pHeader));
//交换结点
//swap_LinkList(pHeader->next,pHeader->next->next);
//printf("%d\n", pHeader->next->data);
//printf("%d\n", pHeader->next->next->data);
//遍历
foreach_LinkList(pHeader);
printf("***************%d\n", size_LinkList(pHeader));
return 0;
}
节点转换图:
运行效果图(第一次正逆遍历是初始化后的,第二次是排序后的):
-------------------------------------------------------END-------------------------------------------------------