简单插入排序,实现非空双向链表升序排列

0x00数据结构考研算法题

比较简单,题目给出节点形式为[priori data next],表头指针为head。要求做插入而不是替换值。

思路:这种类型的题目,尽量思路简单粗暴,一眼能看懂即可。暂不考虑时间空间复杂度。且只写出代码具体实现框架,细节不做处理

0x01

首先创立节点,头pre,不存储数据,只为方便使用

ListNode *per = malloc(sizeof(ListNode));//头pre
pre->next = head;//head不是指针 是受源节点
head->pri = pre;
ListNode *small = head;//给head一个指针small

将pre与链表相连,同时给出head的指针small

0x02

接下来就是实现如何插入了,对其进行while循环,判断当前small所指向节点与后续节点比较,如果大于,则借助指针,提出head,并对其交换。

while(small != NULL){
    ListNode *next = small->next;
    //开始提出head
    small->pri->next = small->next;
    small->next->pri = small->pri;
    small->next = NULL;
    small->pri = NULL;

然后开始判断节点大小,如果small所指位置data,比接下来所指data大,则继续向后比较。这里再引入test指针,指向pre

ListNode *test = pre;//从头节点开始
    while(test->next->data != NULL && small->data > test->next->data ){//small所指与头节点的下一个
        test = test->next;
    }

当不满足while条件时,意味着small<test,此时进行插入,但同时也要注意test移动后的所指向下一个节点是否为空

    if(test->next != NULL){
        small = test->next->pri;
    }
    test->next = small;
    test = small->pri;

注意,此时由于已经提出了head,也就是small,正常情况下交换肯定会变换small的位置,因此上面设置了ListNode *next = small->next;

    small = next;//small和next都是地址,如果保持原样,则相当于small往后移动一个到next

这样就能保证,如果交换了,则small仍是第一个位置,如果不交换,也就是满足升序,small后移

0x03

目前已经大致实现排序,但是问题在于此时陷入死循环,因此借助刚刚的small,如果皆为升序,则small会不断后移,最终移动到最后一个元素位置

    if (small != NULL && small->next == NULL) {
        break; // 全为小大时,即small到了最后 退出循环
    }

此时判断,符合条件break出while

0x04

最终大致代码

ListNode *per = malloc(sizeof(ListNode));//头pre
pre->next = head;//head不是指针 是受源节点
head->pri = pre;
ListNode *small = head;//给head一个指针small
while(small != NULL){
    ListNode *next = small->next;
    //开始提出head
    small->pri->next = small->next;
    small->next->pri = small->pri;
    small->next = NULL;
    small->pri = NULL;
    
    ListNode *test = pre;//从头节点开始
    while(test->next->data != NULL && small->data > test->next->data ){//small所指与头节点的下一个
        test = test->next;
    }
    small->next = test->next;//运行到这一步,肯定是小于,所以插入
    if(test->next != NULL){
        small = test->next->pri;
    }
    test->next = small;
    test = small->pri;
    
    small = next;//small和next都是地址,如果保持原样,则相当于small往后移动一个到next
    
    if (small != NULL && small->next == NULL) {
        break; // 全为小大时,即small到了最后 退出循环
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值