DAY8,写一个双向链表的快速排序函数

题目

写一个双向链表的快速排序函数

思路

/* 递归 大致思路

递进阶段:

以基准,将数据分成'大于基准'和'小于基准'的两份(单次快排);

对'基准左边'重复上述操作;

函数出口:'基准左边'只有一个数

回归阶段:返回到上一层(类似二叉树的构建,左子树)

递进阶段:

对'基准右边'重复上述操作;

函数出口:'基准左边'只有一个数

回归阶段:返回到上一层(类似二叉树的构建,右子树)

*/

代码

link.c文件

复制代码
#include "link.h"

void SortData(const linklistPtr lift,const linklistPtr right)
{
    //检测地址合法,应考虑链表为空情况?

    //函数出口
    if(lift==right||lift==NULL||right==NULL){return;}    //指向同一个节点,或则,说明排序完毕

    //运行到此,说明链表需要排序,准备指针,用于遍历比较
    linklistPtr head=lift;    //复制头指针
    linklistPtr tail=right;   //复制尾指针

    //进行一次快排
    DataType index=head->data;      //选定基准
    while(1)
    {
        //基准与右边比较
        while(index<=tail->data&&head!=tail)    //比基准大,放右边不动,继续向左偏移,判断下一个数据
        {  
            tail=tail->prev;    //向左偏移
        }
        if(head==tail){break;}  //如果是因为head==tail而退出的循环,则无需再交换数据,直接退出     
        head->data=tail->data;    //因为值比基准小而退出,此值应该放在左边 当前head指向的节点
        head=head->next;    //继续向左偏移
        //轮到基准与左边比较
        while(index>=head->data&&head!=tail)
        {
            head=head->next;    //继续向左偏移
        }
        if(head==tail){break;}  //如果是因为head==tail而退出的循环,则无需再交换数据,直接退出
        tail->data=head->data;    //因为值比基准大而退出,大值应该放在右边 当前tail指向的节点
        tail=tail->prev;
       
    }
    printf("tips:单次快排完成,已退出循环\n");
    //运行到次,说明head==tail,一次快排完成,将基准放入tail节点
    tail->data=index;

    //递进阶段
    SortData(lift,tail->prev);    //以基准为界,将数分成左半边和右半;分别排序
    SortData(tail->next,right);   //当tail为 ligt---right 首位时,next prev可能传入NULL?
}

linklistPtr CreatLinkList(void)
{
	//堆区申请
	linklistPtr H=(linklistPtr)malloc(sizeof(linklist));
	if(NULL==H){return NULL;}
	//头节点指针域 赋值 初始值
	H->next=NULL;
    H->prev=NULL;
	//头节点数据域 赋值 初始值
	H->tail=H;
	return H;
}
//申请节点 封装数据
linklistPtr CreatNode(DataType e)
{
	//堆区申请
	linklistPtr newnode=(linklistPtr)malloc(sizeof(linklist));
	if(NULL==newnode){return NULL;}
	//普通节点指针域 赋值 初始值
	newnode->next=NULL;
    newnode->prev=NULL;
	//普通节点数据域 赋值 初始值
	newnode->data=e;
	return newnode;
}

void AddData(linklistPtr H,DataType e)
{
	linklistPtr newnode=CreatNode(e);
	if(NULL==newnode||NULL==H){return;}
    //本节点处理
    newnode->prev=H->tail;//本节点上一个节点,应为 原来的尾节点
    //上一个节点处理
    H->tail->next=newnode;//原尾节点,下一个节点,为本节点;;上一个节点不变
	//尾指针 指向 本节点
	H->tail=newnode;
}

void ShowData(const linklistPtr H)
{
	if(NULL==H){return;}
	linklistPtr temp=H;
	printf("tips:当前链表中数据为:");	
	while(temp->next!=NULL)			//下一个节点不为空
	{
		temp=temp->next;			//成为下一个节点
		printf("%d ",temp->data);	//输出节点内容
	}
	printf("\n\n");	
}

main.c文件

复制代码
#include "link.h"

int main(int argc, const char *argv[])
{
	//创建链表 头节点
	linklistPtr H=CreatLinkList();
	//手动添加数据
	AddData(H,1);
	AddData(H,3);
	AddData(H,5);
	AddData(H,7);
	AddData(H,9);
	AddData(H,2);
	AddData(H,4);
	AddData(H,6);
	AddData(H,8);
	AddData(H,0);
	//显示当前链表上数据
	ShowData(H);
	//快速排序
	SortData(H->next,H->tail);
	ShowData(H);
	return 0;
}

link.h文件

复制代码
typedef int DataType;

typedef struct linklist
{
	struct 
	{
		DataType data;				//普通节点数据域
		struct linklist *tail;		//头节点数据域
	};
	struct linklist *next;			//指针域,指向下一个节点
	struct linklist *prev;		    //指针域,指针上一个节点
}linklist,*linklistPtr;

void TextInit(const char* ch);			//文件初始化
linklistPtr CreatLinkList(void);		//创建头节点
linklistPtr CreatNode(DataType e);		//申请节点 封装数据
void AddData(linklistPtr H,DataType e);	//添加数据
void ShowData(const linklistPtr H);		//显示链表上的数据
void SortData(const linklistPtr lift,const linklistPtr right);

效果

相关推荐
程序员张341 分钟前
Maven编译和打包插件
java·spring boot·maven
ybq195133454312 小时前
Redis-主从复制-分布式系统
java·数据库·redis
weixin_472339462 小时前
高效处理大体积Excel文件的Java技术方案解析
java·开发语言·excel
小毛驴8503 小时前
Linux 后台启动java jar 程序 nohup java -jar
java·linux·jar
枯萎穿心攻击3 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
DKPT3 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
Eiceblue4 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
好奇的菜鸟5 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
m0_555762905 小时前
Matlab 频谱分析 (Spectral Analysis)
开发语言·matlab
DuelCode6 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis