IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 常见排序算法,自己记录 -> 正文阅读

[数据结构与算法]常见排序算法,自己记录

说明

1、稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 仍然在 b 的前面,则为稳定排序。

2、非稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 可能不在 b 的前面,则为非稳定排序。

3、原地排序:原地排序指在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。

4、非原地排序:需要利用额外的数组来辅助排序。

5、时间复杂度:一个算法执行所消耗的时间。

6、空间复杂度:运行完一个算法所需的内存大小。

性能分析

在这里插入图片描述

直接贴代码片:

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<stack>
#include <algorithm>
using namespace std;

// 冒泡排序
void BubbleSort(int* a,int n)
{
	int end = n;
	int exchange = 0;
	while(end)//end作为每趟排序的终止条件
    {
		for(int i=1;i<end;++i)
		{
			if(a[i-1] > a[i])
			{
				swap(a[i-1],a[i]);
				exchange = 1;
			}
		}
		if(0 == exchange)   break;//数组本身为升序,如果一趟排序结束,并没有进行交换,那么直接跳出循环(减少循环次数,升高效率)
		--end;
	}
}


// 递归快排1
void quickSort1(int *a,int left,int right)
{
    int i = left,j = right;
    if(left>right) return;

    while(i<j){
        while(i<j && a[j]>=a[left])
            j--;
        while(i<j && a[i]<=a[left])
            i++;
        if(i<j){
            swap(a[i],a[j]);
        }
    }
    swap(a[i],a[left]);
    quickSort1(a,left,i-1);
    quickSort1(a,i+1,right);
}

// 递归快排2
void quickSort2(int *nums,int begin,int end)
{
    if(begin >= end) return;
    int first = begin,last = end;
    int key = nums[first];
    while(first<last){
        while(first<last && nums[last]>=key)
            last--;
        if(first < last)
            nums[first++] = nums[last];
        while(first<last && nums[first]<=key)
            first++;
        if(first < last)
            nums[last--] = nums[first];
    }

    nums[first] = key;

    quickSort2(nums,begin,first-1);
    quickSort2(nums,first+1,end);
}

// 非递归快排3
// 划分算法
int Partition(int *a,int low,int high)
{
    if(low>=high) return -1;
    int pivot = a[low];// 假设每次都以第一个元素作为枢轴值,进行一次划分: 
    while(low<high){
        while(low<high && a[high]>=pivot)
            high--;
        if(low<high)
            a[low++] = a[high];
        while(low<high && a[low]<=pivot)
            low++;
        if(low<high)
            a[high--] = a[low];
    }
    a[low] = pivot;// pivot的最终落点
    return low;
}

void quickSort3(int *a,int left,int right)
{
    // 利用栈来存储每次分块快排的起始点
    if(left >= right) return;
    stack<int> s;
    int mid = Partition(a,left,right);
    if(mid-1 > left){ // 确保左分区存在
        // 将左分区端点入栈
        s.push(left);
        s.push(mid-1);
    }
    if(mid+1 < right){ // 确保右分区存在
        // 将右分区端点入栈
        s.push(mid+1);
        s.push(right);
    }
    // 栈非空时循环获取中轴入栈
    while(!s.empty()){
        // 得到某分区的左右边界
        int r = s.top();
        s.pop();
        int l = s.top();
        s.pop();
        mid = Partition(a,l,r);
        if(mid-1 > l){
            s.push(l);
            s.push(mid-1);
        }
        if(mid+1 < r){
            s.push(mid+1);
            s.push(r);
        }
    }
}

// 插入排序
 vector<int> insertSort(vector<int>& nums)
 {
    int n = nums.size();
    for(int i=1;i<n;i++){
        int flag = nums[i];
        int j = i - 1;
        while(j>=0 && nums[j]>flag){
            nums[j+1] = nums[j];
            j--;
        }
        nums[j+1] = flag;
    }
    return nums;
}

// 希尔排序(高级插入排序)
vector<int> shellSort(vector<int>& nums)
{
    int n = nums.size();
    int h = 1;
    while(h<n/3)
        h = 3*h+1;
    while(h>0)
    {
        for(int i=h;i<n;i++)
        {
            int j = i-h;
            int flag = nums[i];
            while(j>=0 && flag<nums[j])
            {
                nums[j+h] = nums[j];
                j = j-h;
            }
            nums[j+h] = flag;
        }
        h = h/3;
    }
    return nums;
}

// 选择排序
void selectSort(int *a,int n)
{
	int begin = 0;
	int end = n-1;
	while (begin < end)
	{
		int min = begin,max = begin;
		for(int i=begin;i<=end;++i)
		{
			if(a[min] > a[i])
				min = i;
			if(a[max] < a[i])
				max = i;
		}
		swap(a[min],a[begin]);
		if(max == begin)//如果首元素是最大的,则需要先把min 和 max的位置一换,再交换,否则经过两次交换,又回到原来的位置
			max = min;
		swap(a[max],a[end]);
		begin++;
		end--;
	}
}


//堆排序
    void AdjustDown(vector<int>& a, int root, int n)
    {
        int parent = root;
        int child = parent*2+1; // 左子
        while( child < n ){
            if( (child+1) < n && a[child+1] > a[child] ){
                ++child;
            }
            if( a[child] > a[parent] ){
                swap(a[child],a[parent]);
                parent = child;
                child = parent*2+1;// 到下一个子树
            }
            else
                break;
        } 
    }

    void heapSort(vector<int>& a, int n) 
    {
        // 找到终端节点
        for( int i = n/2-1; i >=0 ; i-- )
            AdjustDown(a,i,n);
        int end = n - 1;
        while( end > 0 ){
            swap(a[0],a[end]);
            AdjustDown(a,0,end);
            end--;
        }
    }


 // 归并排序
void Merge(int* a, int left, int mid, int right)
{
	int *temp = new int[right - left + 1];  //申请空间存放合并数组
    int st1 = left,st2 = mid + 1;
	int t = 0;

	while (st1 <= mid && st2 <= right) 
		temp[t++] = a[st1] < a[st2] ? a[st1++] : a[st2++];

	while (st1 <= mid) // st2已放置完成,st1剩余
		temp[t++] = a[st1++];

	while (st2 <= right) // st1已放置完成,st2剩余
		temp[t++] = a[st2++];

	for (int j = 0; j < t; ++j) //把临时创建的数组拷贝至原数组
		a[left + j] = temp[j];

	delete[] temp; //销毁临时变量
}
void mergeSort(int* a, int start, int end){
	if (a==NULL || start>=end)
		return;

		int mid = (start + end) >> 1;  // 找到每个分块的中间值
		mergeSort(a, start, mid);
		mergeSort(a, mid + 1, end);
		Merge(a, start, mid, end); // 左右合并
}


// 桶排序,用了vector<int>的快排
void bucketSort(vector<int>& shit){
    int max = 0,min = 0,n = shit.size();
    for(int n:shit){
        if(max < n) max = n;
        if(min > n) min = n;
    }
    int gap = (max-min) / n + 1;// 间隔
    int count = (max-min) / gap +1;// 桶数
    vector<int> buckets[count];
    for(int n:shit){
        int index = n/gap;
        buckets[index].push_back(n);
    }
    int index = 0;
    for(auto bucket:buckets){
        sort(bucket.begin(),bucket.end());
        for(int m:bucket){
            shit[index++] = m;
        }
    }
}

int main()
{
    int a[12] = {1,2,4,5,11,33,6,77,8,1000,5,12};
    int left = 0, right = 11;
    cout << "before sort:" << endl;
/*    for(int val:a)
        cout << val << " ";
    cout << endl;
*/
    vector<int> shit(a,a+12);
    for(int v:shit)
        cout << v << " ";
    cout << endl;  
      
    //int nums = shit.size();
    //BubbleSort(a,12);
    //quickSort1(a,left,right);
    //quickSort2(a,left,right);
    //quickSort3(a,left,right);
    //insertSort(shit);
    //shellSort(shit);
    //selectSort(a,12); 
    //heapSort(shit,12);
    //mergeSort(a,left,right);
    //bucketSort(shit);

    cout << "after sort:" << endl; 
    for(int v:shit)
        cout << v << " ";

/*    for(int val:a)
        cout << val << " ";
*/
    cout << endl;
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:42:15  更:2021-08-31 15:43:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:44:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码