版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}