单链表的直接插入排序

8 篇文章 1 订阅
5 篇文章 0 订阅

单链表的直接插入排序
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值