首页 > 其他分享 >快排及链表排序

快排及链表排序

时间:2023-08-29 12:36:02浏览次数:33  
标签:ListNode val nullptr next 链表 快排 pHead 排序



文章目录

  • 一、普通的快排
  • 二、链表的创建
  • 三、链表的冒泡排序
  • 四、链表快排
  • 五、链表归并排序


一、普通的快排

void QuickSort(vector<int> &vec, int low, int high)
{
	int pivot = vec[low]; // 选择第一个元素作为枢纽元
	// mid总是指向最后一个比枢纽元小的位置,当需要交换元素时,先将mid加1,这时候
	// mid就指向了第一个大于枢纽元的位置
	int mid = low; 
	if (low >= high) return;
	for (int i = low + 1; i <= high; ++i)
	{
		if (vec[i] <= pivot)
		{
			swap(vec[i], vec[++mid]); // 比枢纽元小的都放前面
		}
	}
	swap(vec[low], vec[mid]); // 保证交换到头部的元素比枢纽元小
	QuickSort(vec, low, mid - 1);
	QuickSort(vec, mid + 1, high);
}

// 调用
QuickSort(num, 0, num.size()-1);

二、链表的创建

struct ListNode
{
	int val;
	ListNode *next;
	ListNode(int value) : val(value), next(nullptr) {}
};

ListNode *CreateList(vector<int> vec)
{
	ListNode *pHead = new ListNode(vec[0]);
	ListNode *pTmp = pHead;
	int cnt = 1, sz = vec.size();
	while (cnt < sz)
	{
		ListNode *pCurrent = new ListNode(vec[cnt]);
		pTmp->next = pCurrent;
		pTmp = pCurrent;
		cnt++;
	}
	pTmp->next = nullptr;
	return pHead;
}
void ShowList(ListNode* pHead)
{
	while (pHead)
	{
		cout << pHead->val << " ";
		pHead = pHead->next;
	}
	cout << endl;
}

三、链表的冒泡排序

与普通的冒泡排序类似,pHead1控制次数,pHead2 用于比较和交换。

ListNode* BubbleSortList(ListNode* pHead)
{
	if (pHead == nullptr)
		return nullptr;
	ListNode *pHead1, *pHead2;
	for (pHead1 = pHead; pHead1->next != nullptr; pHead1 = pHead1->next)
	{
		for (pHead2 = pHead; pHead2->next != nullptr; pHead2 = pHead2->next)
		{
			// 相邻元素比较交换
			if (pHead2->val > pHead2->next->val)
				swap(pHead2->val, pHead2->next->val);
		}
	}
	return pHead;
}

// 调用
ListNode* pHead = CreateList(vec);
BubbleSortList(pHead);

四、链表快排

和普通的快排基本上没有区别。

void QuickSortList(ListNode* pBegin, ListNode* pEnd)
{
	// 选取第一个结点为枢纽元,pmid 总是指向最后一个小于等于枢纽元的结点
	ListNode* pivot = pBegin, *pmid = pBegin, *ptmp;
	if (pBegin == pEnd || pBegin == nullptr) return;
	for (ptmp = pBegin->next; ptmp != pEnd; ptmp = ptmp->next)
	{
		if (ptmp->val <= pivot->val)
		{
			pmid = pmid->next;
			swap(ptmp->val, pmid->val);
		}
	}
	swap(pmid->val, pBegin->val);
	QuickSortList(pBegin, pmid);
	QuickSortList(pmid->next, pEnd);
}

// 调用
ListNode* pHead = CreateList(vec);
QuickSortList(pHead, nullptr);

快排及链表排序_冒泡排序

五、链表归并排序

Node* MergeSort(Node* node) {
	// 先判断链表长度是否大于1,小于1时无须排序
	if (node != nullptr && node->next != nullptr) {
		// 运用快慢指针,找到链表的中间节点
		Node *fast = node->next;
		Node *slow = node;
		while (fast != nullptr && fast->next != nullptr) {
			fast = fast->next->next;
			slow = slow->next;
		}

		// 将链表分成两部分进行分割
		Node *p1 = MergeSort(slow->next);
		slow->next = NULL; // slow
		Node *p2 = MergeSort(node);

		// 对两段子链表进行归并
		Node *p0 = (Node *)malloc(sizeof(Node));
		Node *p = p0;
		while (p1 != NULL && p2 != NULL) {
			if (p1->val < p2->val) {
				p->next = p1;
				p1 = p1->next;
			}
			else {
				p->next = p2;
				p2 = p2->next;
			}
			p = p->next;
		}

		if (p1 != NULL) {
			p->next = p1;
		}

		if (p2 != NULL) {
			p->next = p2;
		}

		p = p0->next;
		free(p0);
		return p;
	}
	return node;
}


标签:ListNode,val,nullptr,next,链表,快排,pHead,排序
From: https://blog.51cto.com/u_6526235/7274778

相关文章

  • 快速排序
    快速排序是一种常见的排序算法,它的基本思想是通过分治的策略将一个大问题拆分为若干个小问题,并通过递归求解这些小问题,最终将整个问题排序完成。具体的步骤如下:选择一个基准元素,一般选择第一个元素。将序列中小于等于基准元素的元素移动到基准元素的左边,大于基准元素的元素移......
  • 希尔排序整理
    算法原理代码实现1publicstaticvoidsort(int[]array){2//数据间隔h8>4>2>13inth=array.length/2;4while(h>=1){5for(intstart=0;start<h;start++){6//对start,start+h,......
  • 876 , 链表的中间节点
    https://leetcode.cn/problems/middle-of-the-linked-list/ 使用快慢指针1lassSolution{2publicListNodemiddleNode(ListNodehead){3//排除为空情况4if(head==null){5returnnull;6}7//使用......
  • 数组二分查找:35. 搜索插入位置、34. 在排序数组中查找元素的第一个和最后一个位置
    35. 搜索插入位置1classSolution:2defsearchInsert(self,nums:List[int],target:int)->int:3left,right=0,len(nums)-145whileleft<=right:#左闭右闭6mid=left+(right-left)//27ifnum......
  • 【C++STL基础入门】vector运算和遍历、排序、乱序算法
    @TOC前言C++标准库提供了丰富的容器和算法,其中vector是最常用的容器之一。它以动态数组的形式存储元素,并提供了许多方便的运算符和算法来操作和处理数据。本文将介绍vector的基本运算、遍历方法、排序算法以及乱序算法。通过学习这些内容,您将能够更加灵活、高效地使用vector容器。......
  • 冒泡排序
    冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的元素,并根据需要交换它们的位置,直到整个列表排序完成为止。具体步骤如下:从列表的第一个元素开始,比较它与下一个元素的大小。如果当前元素较大,则交换它与下一个元素的位置。继续向列表的下一个元素进行比较,重复......
  • 实现-双向链表
    1/*2简介:双向链表,可在头尾实现插入和删除3注意:这个双向链表不形成环4作者:njit-sam(许言)5*/67#include<stdio.h>8#include<stdlib.h>9#include<string.h>1011typedefstructdouble_linked_list{12intindex;13struc......
  • 插入排序之希尔排序
    1voidshell_sort()2{3unsignedchari=0,j=0,gap;4unsignedchararr[10]={4,1,3,9,6,2,8,5,0,7};5unsignedcharlen=sizeof(arr);6unsignedchartemp;7chark;8gap=len;9while(gap)10{11gap......
  • 插入排序之直接插入排序
    1voidinsert_sort()2{3inti,j;4unsignedchararray[10]={4,1,3,9,6,2,8,5,0,7};5unsignedcharlen=sizeof(array);67/*遍历所有无序序列*/8for(i=1;i<len;i++)9{10unsignedchartemp=array[i];......
  • 简单排序之选择排序
    1voidselect_sort()2{3inti,j,k;4unsignedchararray[10]={4,1,3,9,6,2,8,5,0,7};5unsignedcharlen=sizeof(array);6unsignedchartemp;78for(i=0;i<len-1;i++)9{10k=i;11/*遍历所以有......