单链表的直接插入排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29567701/article/details/80398845

单链表的直接插入排序
1、数组的直接插入排序

void InsertSort(int *a, int len)
{
    for (int i = 1; i < len; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (a[j]>a[i])
            {
                int temp = a[i];
                for (int k = i; k>j; --k)
                    a[k] = a[k - 1];
                a[j] = temp;
            }
        }
    }
}

2、单链表的直接插入排序
自己按本文 数组的直接插入排序 的想法实现的。
有瑕疵,无法对链表第一个结点进行插入排序,往路过的大侠指点一二!!

思路:
与数组插入不同,
数组插入新的数据元素后,第j+1到第i个位置的数据通通后移一位,为 第i个位置的数据元素 赋值到 第j个位置 让路
链表插入新的结点:则是指针的变化。
共5步:
step1:临时链表指针 保存第i个结点pi的下一结点指针
step2:第j个结点pj的前一结点的下一步指向pi(待插结点)
step3:第i个结点pi的下一步指向pj
step4:pi的前一个结点的下一步指向原 第i个结点的下一节点位置
step5:交换当前 p1与pi的节点位置
子函数如下:

void SwapNodesPointer(ListNode *&p1, ListNode *&p2)//交换链表中两结点指针
{
    ListNode *ptemp;
    ptemp = p1, p1 = p2, p2 = ptemp;
}
//单链表直接插入排序----  第一个结点无法参与排序的那种 
void InsertionSort3(ListNode* &pHead)
{
    if(pHead==NULL) return;

    ListNode *pi = pHead->next->next;//pi:指向第3个结点
    ListNode *p1 = pHead->next;//p1:指向pi的前一个结点

    ListNode *pj = pHead->next;//pj:指向第2个结点
    ListNode *p2 = pHead;//p2:指向pj的前一个结点

    while (pi)
    {
        while (pj != pi)
        {
            if (pj->data > pi->data)//执行pi插入到pj的前一个结点 即p2
            {
                ListNode *ptemp = pi->next;//step1:临时链表指针 保存第i个结点pi的下一结点指针
                p2->next = pi;//step2:第j个结点pj的前一结点的下一步指向pi(待插结点)
                pi->next = pj;//step3:第i个结点pi的下一步指向pj
                p1->next = ptemp;//step4:pi的前一个结点的下一步指向原 第i个结点的下一节点位置
                SwapNodesPointer(p1, pi);//step5:交换当前 p1与pi的节点位置
            }
            p2 = p2->next;//第j个结点 及其前一节点 后移一位
            pj = p2->next;
        }
        if (pi->next == NULL) break;
        p1 = p1->next;//第i个结点 及其前一节点 后移一位
        pi = p1->next;

        //第j个结点 及其前一节点(pj,p2)归位,置于链表表头,准备下一轮的循环
        p2 = pHead;
        pj = p2->next;
    }
}

3、测试代码

#include<iostream>
using namespace std;

struct ListNode
{
    int data;
    ListNode* next;
};

ListNode* CreateNode(int value)
{
    ListNode *p = new ListNode();
    p->data = value;
    p->next = NULL;
    return p;
}

void ConnecteNodes(ListNode *p1, ListNode *p2)
{
    if (p1 == NULL)//错误代码:  while (p1 == NULL)
        return;
    p1->next = p2;
}

void DispList(ListNode* &p)
{
    if (p == NULL)
        return;
    ListNode *pnode = p;
    while (pnode)
    {
        cout << pnode->data;
        if (pnode->next)
            cout << "->";
        pnode = pnode->next;//  错误代码:pnode = p->next;
    }
    cout << endl;
}

void DestroyList(ListNode *p)
{
    ListNode* pnode = p;
    while (pnode)
    {
        p = p->next;
        delete pnode;
        pnode = p;
    }
}

//--------------------------------------------------------------------------
void SwapNodesPointer2(ListNode *&p1, ListNode *&p2)
{
    ListNode *ptemp;
    ptemp = p1, p1 = p2, p2 = ptemp;
}
//单链表直接插入排序----  第一个结点无法参与排序的那种 
void InsertionSort3(ListNode* &pHead)
{
    if(pHead==NULL) return;

    ListNode *pi = pHead->next->next;//pi:指向第3个结点
    ListNode *p1 = pHead->next;//p1:指向pi的前一个结点

    ListNode *pj = pHead->next;//pj:指向第2个结点
    ListNode *p2 = pHead;//p2:指向pj的前一个结点

    while (pi)
    {
        while (pj != pi)
        {
            if (pj->data > pi->data)//执行pi插入到pj的前一个结点 即p2
            {
                ListNode *ptemp = pi->next;//step1:临时链表指针 保存第i个结点pi的下一结点指针
                p2->next = pi;//step2:第j个结点pj的前一结点的下一步指向pi(待插结点)
                pi->next = pj;//step3:第i个结点pi的下一步指向pj
                p1->next = ptemp;//step4:pi的前一个结点的下一步指向原 第i个结点的下一节点位置
                SwapNodesPointer(p1, pi);//step5:交换当前 p1与pi的节点位置
            }
            p2 = p2->next;//第j个结点 及其前一节点 后移一位
            pj = p2->next;
        }
        if (pi->next == NULL) break;
        p1 = p1->next;//第i个结点 及其前一节点 后移一位
        pi = p1->next;

        //第j个结点 及其前一节点(pj,p2)归位,置于链表表头,准备下一轮的循环
        p2 = pHead;
        pj = p2->next;
    }
}
void test2_2()
{
    cout << "-------InsertionSort3()----------" << endl;

    ListNode *p1 = CreateNode(10);
    ListNode *p2 = CreateNode(6);
    ListNode *p3 = CreateNode(2);
    ListNode *p4 = CreateNode(15);
    ListNode *p5 = CreateNode(8);
    ListNode *p6 = CreateNode(3);
    ListNode *p7 = CreateNode(1);
    ListNode *p8 = CreateNode(9);

    ConnecteNodes(p1, p2);
    ConnecteNodes(p2, p3);
    ConnecteNodes(p3, p4);
    ConnecteNodes(p4, p5);
    ConnecteNodes(p5, p6);
    ConnecteNodes(p6, p7);
    ConnecteNodes(p7, p8);

    DispList(p1);//10->6->2->15->8->3->1->9
    InsertionSort3(p1);
    DispList(p1);//10->1->2->3->6->8->9->15 
    DestroyList(p1);
}
int main()
{
    test2_2();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_29567701/article/details/80398845