基于单链表的插入排序

  1. 给定一个单链表,如何完成插入排序;

  2. 单链表排序最好的方法就是插入排序。单链表的处理方式要注意一下几点,(1)处理A节点的时候,记得保留A-nex它的节点。(2)涉及到头结点变换的时候,最好定义一个变量专门保存变换后的头结点。以便直接返回。(3)涉及到节点删除和节点替换等操作,记得保留节点的上个节点。(当然也可以通过赋值等一系列操作,不用保留上个节点)。(4)进行操作的时候,再插入节点的时候,记得做割裂操作,要不然容易导致死循环。

  3. 链表的插入排序实现方法,我们把头结点和其余节点当做两个链表来完成插入排序。实现的代码如下:

  4. #include
    #include
    #include
    using namespace std;
    typedef struct node
    {
    int val;
    node *next;
    node(int val)
    {
    this->val = val;
    this->next = nullptr;
    }
    node()
    {
    this->next = nullptr;
    }
    }LinkNode;
    void insertNode(LinkNode *&head, int val)
    {
    if (head == nullptr)
    {
    head = new LinkNode(val);
    }
    else
    {
    LinkNode *phead = head;
    while (phead->next != nullptr)
    {
    phead = phead->next;
    }
    phead->next = new LinkNode(val);
    }
    }
    void display(LinkNode *head)
    {
    if (head->next)
    {
    display(head->next);
    }
    cout << head->val << " ";
    }
    LinkNode *insertSort(LinkNode *head)
    {
    LinkNode *phead = head;//需要插入节点链表的头结点
    LinkNode *temp = head->next;//插入的节点的下一个节点
    LinkNode *cal = temp;//带插入的节点
    phead->next = nullptr;//这一步很重要,意味着重新生成一个新的链表。而且一定要放在这个位置。
    LinkNode *fronthead = head;//进行插入运算的时候的上个节点
    LinkNode *head_final = head;//需要返回的头结点
    while (cal != nullptr)
    {
    temp = cal->next;//保留插入节点的下一个节点,
    cal->next = nullptr;//需要插入的节点,需要和后面的节点割裂开来。要不然会进入死循环,因为一直插入,会导致cal->next 一直不为空。
    while (phead != nullptr && phead->val > cal->val)
    {
    fronthead = phead;
    phead = phead->next;
    }
    if (fronthead == phead)//当着两个节点想等的时候,说明cal的值大于phead节点。
    {
    cal->next = fronthead;
    fronthead = cal;
    head_final = fronthead;//保留最新的头结点
    }
    else
    {
    if (phead == nullptr)
    {
    fronthead->next = cal;
    }
    else
    {
    fronthead->next = cal;
    cal->next = phead;
    }
    }
    phead = head_final;
    fronthead = head_final;//保留最新的头结点
    cal = temp;//进行下一个节点的插入。

    }
    return head_final;
    }
    void print(LinkNode *node)
    {
    while (node)
    {
    cout << node->val << " ";
    node = node->next;
    }
    cout << endl;
    }
    int main()
    {
    LinkNode *head = nullptr;
    srand((unsigned)time(NULL));
    for (int i = 0; i < 10; i++)
    {
    int val = rand() % 100;
    insertNode(head, val);
    cout << val << " ";
    }
    cout << endl;
    print(head);
    LinkNode *sorthead=insertSort(head);
    print(sorthead);
    system(“pause”);
    return 0;
    }
    运行结果如下:
    在这里插入图片描述
    链表处理基本上需要前面描述的四个要点。链表的割裂操作很重要,什么时候割裂,为什么割裂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值