c++排序算法

1. 快速排序

https://blog.youkuaiyun.com/yang_yi520/article/details/124967724

#include<iostream>
 
using namespace std;
 
void quickSort(int arr[], int begin, int end) {
	if (begin >= end) return;
	int left = begin;
	int right = end;
	int temp = arr[left];
 
	while (left < right) {
		//从后往前找比他小的放前面,从前往后找比它大的放后面
		//以第一个数为基准,必须先从后往前走,再从前往后走
		while (left < right && arr[right] >= temp) {
			right--;
		}  //跳出此循环,代表right找到了比temp小的数字,所以此时arr[left]=arr[right]
		if (left < right) {
			arr[left] = arr[right];
		}
		while (left < right && arr[left] <= temp) {
			left++;
		}//同理
		if (left < right) {
			arr[right] = arr[left];
		}
		if (left == right) {
			arr[left] = temp;
		}
	}
	quickSort(arr, begin, left - 1);
	quickSort(arr, left + 1, end);
}
int main() {
 
	int arr[11] = { 5,6,3,2,7,8,9,1,4,0,0 };
	quickSort(arr, 0, 10);
	for (auto x : arr) {
		cout << x << " ";
	}
	return 0;
}

2. 冒泡排序

void BubbleSort(vector<int>& v) {
	int len = v.size();
	for (int i = 0; i < len - 1; ++i)
		for (int j = 0; j < len - 1 - i; ++j)
			if (v[j] > v[j + 1]) 
				swap(v[j], v[j + 1]);
}

改进

void BubbleSort_orderly(vector<int>& v) {
	int len = v.size();
	bool orderly = false;
	for (int i = 0; i < len - 1 && !orderly; ++i) {
		orderly = true;
		for (int j = 0; j < len - 1 - i; ++j) {
			if (v[j] > v[j + 1]) {  // 从小到大
				orderly = false;	// 发生交换则仍非有序
				swap(v[j], v[j + 1]);
			}
		}
	}
}

3. 选择排序

void SelectionSort(vector<int>& v) {
	int min, len = v.size();
	for (int i = 0; i < len - 1; ++i) {
		min = i;
		for (int j = i + 1; j < len; ++j) {
			if (v[j] < v[min]) {    // 标记最小的
				min = j;
			}
		}
		if (i != min)  // 交换到前面
			swap(v[i], v[min]);
	}
}

4. 插入排序

void InsertSort(vector<int>& v)
{
    int len = v.size();
	for (int i = 1; i < len; ++i) {
		int temp = v[i];
        for(int j = i - 1; j >= 0; --j)
        {
            if(v[j] > temp)
            {
                v[j + 1] = v[j];
                v[j] = temp;
            }
            else
                break;
        }
	}
}

5. 希尔排序

template<typename T>
void shell_sort(T array[], int length) {
    int h = 1;
    while (h < length / 3) {
        h = 3 * h + 1;
    }
    while (h >= 1) {
        for (int i = h; i < length; i++) {
            for (int j = i; j >= h && array[j] < array[j - h]; j -= h) {
                std::swap(array[j], array[j - h]);
            }
        }
        h = h / 3;
    }
}

6. 归并排序

排序算法:归并排序【图解+代码】

7. 堆排序 

排序算法:堆排序【图解+代码】

#include<iostream>
 
using namespace std;
void sw(int &a,int &b) {
	int temp = a;
	a = b;
	b = temp;
}
// arr[]为完全二叉树层序遍历得到的数组
// n为完全二叉树的节点,即数组长度
// i为待维护的节点
void heapify(int arr[], int n, int i) {    //把这个二叉树先堆化
 
	//递归出口
	if (i >= n) return;
 
	int largest = i;
	int lson = i * 2 + 1;
	int rson = i * 2 + 2;
	if (lson < n && arr[largest] < arr[lson]) {  //和左孩子数值比较,找到最大节点,赋值下标
		largest = lson;
	}
	if (rson < n && arr[largest] < arr[rson]) {  //和右孩子数值比较,找到最大节点,赋值下标
		largest = rson;
	}
	if (largest != i) {   //如果现在的最大值下标和之前的不一样,那么交换二者的数值
		//sw(arr[largest], arr[i]);
		swap(arr[largest], arr[i]);
		heapify(arr, n, largest); //进行一个递归,因为在上一层的节点交换完之后,无法保证下边父节点大于孩子节点
	}
 
}
void heap_sort(int arr[], int n) {
	//建堆
	int lastNode = n - 1;    //从后往前建堆
	int parent = (lastNode - 1) / 2;
	for (int i = parent; i >= 0; i--) {
		heapify(arr, n, i);
	}
 
	//堆排序
	for (int i = n - 1; i >= 0; i--) {
		sw(arr[i], arr[0]);
		heapify(arr, i, 0);
	}
}
int main() {
	int arr[5] = { 5,4,3,2,1 };
	heap_sort(arr, sizeof(arr) / sizeof(arr[0]));
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
		cout << arr[i] << endl;
	}
 
	return 0;
}

8 计数排序

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 计数排序
void CountSort(vector<int>& vecRaw, vector<int>& vecObj)
{
	// 确保待排序容器非空
	if (vecRaw.size() == 0)
		return;

	// 使用 vecRaw 的最大值 + 1 作为计数容器 countVec 的大小
	int vecCountLength = (*max_element(begin(vecRaw), end(vecRaw))) + 1;
	vector<int> vecCount(vecCountLength, 0);

	// 统计每个键值出现的次数
	for (int i = 0; i < vecRaw.size(); i++)
		vecCount[vecRaw[i]]++;
	
	// 后面的键值出现的位置为前面所有键值出现的次数之和
	for (int i = 1; i < vecCountLength; i++)
		vecCount[i] += vecCount[i - 1];

	// 将键值放到目标位置
	for (int i = vecRaw.size(); i > 0; i--)	// 此处逆序是为了保持相同键值的稳定性
		vecObj[--vecCount[vecRaw[i - 1]]] = vecRaw[i - 1];
}

int main()
{
	vector<int> vecRaw = { 0,5,7,9,6,3,4,5,2,8,6,9,2,1 };
	vector<int> vecObj(vecRaw.size(), 0);

	CountSort(vecRaw, vecObj);

	for (int i = 0; i < vecObj.size(); ++i)
		cout << vecObj[i] << "  ";
	cout << endl;

	return 0;
}
#include<iostream>
#include<vector>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int>arr(n);
    int count[1000] = {0};
    vector<int>result(n);
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
        count[arr[i]]++;
    }
    for (int i = 1; i < 1000; ++i) {
        count[i] = count[i - 1] + count[i];
    }
    for (int i = n - 1; i >= 0; --i) {
        result[count[arr[i]] - 1] = arr[i];
        count[arr[i]]--;
    }
    for (int i = 0; i < n; ++i)
        cout << result[i] << " ";
    return 0;

}

 

自己写的 

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

int main() {
    int n;
    cin >> n;
    vector<int>arr(n);
    vector<int>result(n);
    int max = INT_MIN;
    int min = INT_MAX;
    //输入并且记录最大值最小值
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
        if(arr[i] < min) min = arr[i];
        if(arr[i] > max) max=arr[i];
    }
    //创建数组
    int len = max - min;
    vector<int> count(len + 1, 0);
    //记录个数
    for (int i = 0; i < n; ++i) {
        int index = arr[i] - min;
        count[index]++;
    }
    //输出
    int j = 0;
    for (int i = 0; i < count.size();i++) {
       
        while(count[i]!=0){
            result[j] = i + min;
            j++;
            count[i]--;
        }
        
    }
    for (int i = 0; i < n; ++i)
        cout << result[i] << " ";
    return 0;

}

9.桶排序

#include <bits/stdc++.h>
using namespace std;
 
// 打印数组
void print_array(int *arr, int n) {
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++) 
        printf(" %d", arr[i]);
    printf("\n");
}
 
 
int* sort_array(int *arr, int n) {
    int i;
	int maxValue = arr[0];
	for (i = 1; i < n; i++) 
		if (arr[i] > maxValue)  // 输入数据的最大值
			maxValue = arr[i]; 
	
	// 设置10个桶,依次0,1,,,9
	const int bucketCnt = 10;
	vector<int> buckets[bucketCnt];
	// 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
	// 最大值999,桶大小100
	// 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
	int bucketSize = 1;
	while (maxValue) {		//求最大尺寸 
		maxValue /= 10;
		bucketSize *= 10;
	}
	bucketSize /= 10;		//桶的个数 
	// 入桶
	for (int i=0; i<n; i++) {
		int idx = arr[i]/bucketSize;			//放入对应的桶 
		buckets[idx].push_back(arr[i]);
		// 对该桶使用插入排序(因为数据过少,插入排序即可),维持该桶的有序性
		for (int j=int(buckets[idx].size())-1; j>0; j--) {
			if (buckets[idx][j]<buckets[idx][j-1]) {
				swap(buckets[idx][j], buckets[idx][j-1]);
			}
		}
	}
	// 顺序访问桶,得到有序数组
	for (int i=0, k=0; i<bucketCnt; i++) {
		for (int j=0; j<int(buckets[i].size()); j++) {
			arr[k++] = buckets[i][j];
		}
	}
	return arr;
}
 
 
 
int main() {
    int n;
    scanf("%d", &n);
    
    int *arr;
    arr = (int*)malloc(sizeof(int)*n);
    
    for (int i=0; i<n; i++) scanf("%d", &arr[i]);
    
    arr = sort_array(arr, n);
    
    print_array(arr, n);
    
    system("pause"); 
    return 0;
}

自己写的(牛客网)

class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型vector
     * @return int整型vector
     */
    vector<int> bucketSort(vector<int>& nums) {
        // write code here
        // 计入输入的最大值
        int maxValue = nums[0];
        for (int i = 1; i < nums.size(); i++)
            if (nums[i] > maxValue)  // 输入数据的最大值
                maxValue = nums[i];
        // 全是零的数组
        if(maxValue == 0){
            return nums;
        }
        // 设置10个桶,依次0,1,,,9
        const int bucketCnt = 10;
        vector<int> buckets[bucketCnt];
        // 桶的大小bucketSize根据数组最大值确定:比如最大值99, 桶大小10
        // 最大值999,桶大小100
        // 根据最高位数字映射到相应的桶,映射函数为 arr[i]/bucketSize
        int bucketSize = 1;
        while (maxValue) {      //求最大尺寸
            maxValue /= 10;
            bucketSize *= 10;
        }
        bucketSize /= 10;       //桶的个数
        // 入桶
        for (int i = 0; i < nums.size(); i++) {
            int idx = nums[i] / bucketSize;           //放入对应的桶
            buckets[idx].push_back(nums[i]);
            // 对该桶使用插入排序(因为数据过少,插入排序即可),维持该桶的有序性
            for (int j = int(buckets[idx].size()) - 1; j > 0; j--) {
                if (buckets[idx][j] < buckets[idx][j - 1]) {
                    swap(buckets[idx][j], buckets[idx][j - 1]);
                }
            }
        }
        // 顺序访问桶,得到有序数组
        for (int i = 0, k = 0; i < bucketCnt; i++) {
            for (int j = 0; j < int(buckets[i].size()); j++) {
                nums[k++] = buckets[i][j];
            }
        }
        return nums;
    }
};

10.基数排序

#include <iostream>
#include <vector>
using namespace std;


int MaxBit(vector<int> input)    //求出数组中最大数的位数
{
	int max_num = input[0];      //默认最大数为第一个数字
	for (int i = 0; i < input.size(); i++)  //找出数组中的最大数
	{
		if (input[i] > max_num)
		{
			max_num = input[i];
		}
	}
	int p = 0;
	while (max_num > 0)
	{
		p++;
		max_num /= 10;   //每次除以10取整,即可去掉最低位
	}
	return p;
}

int GetNum(int num, int d)   //取出所给数字的第d位数字
{
	int p = 1;
	while (d - 1 > 0)
	{
		p *= 10;
		d--;
	}
	return num / p % 10;
}

vector<int> RadixSort(vector<int> input, int length)   //基数排序
{
	vector<int> bucket(length);   //创建临时存放排序过程中的数据
	vector<int> count(10);   //创建按位计数的技术容器,即记录排序中按个位、十位...各个数的位置的个数

	for (int d = 1; d <= MaxBit(input); d++) {
		// 计数器清0
		for (int i = 0; i < 10; i++) {
			count[i] = 0;
		}

		// 统计各个桶中的个数
		for (int i = 0; i < length; i++) {
			count[GetNum(input[i], d)]++;
		}

		for (int i = 1; i < 10; i++) {     //得到每个数应该放入bucket中的位置
			count[i] += count[i - 1];
		}

		for (int i = length - 1; i >= 0; i--) {  //采用倒序进行排序是为了不打乱已经排好的顺序
			int k = GetNum(input[i], d);
			bucket[count[k] - 1] = input[i];
			count[k]--;
		}


		for (int j = 0; j < length; j++)    // 临时数组复制到 input 中
		{
			input[j] = bucket[j];
		}
	}
	return input;
}

int main()
{
	int arr[] = { 50, 123, 543, 187, 49, 30, 0, 2, 11, 100 };
	vector<int> test(arr, arr + sizeof(arr) / sizeof(arr[0]));
	cout << "排序前:";
	for (int i = 0; i < test.size(); i++) {
		cout << test[i] << " ";
	}
	cout << endl;

	vector<int> result = test;
	result = RadixSort(result, result.size());
	cout << "排序后:";
	for (int i = 0; i < result.size(); i++) {
		cout << result[i] << " ";
	}
	cout << endl;
	system("pause");
}

牛客网

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<int>nums(n);
    vector<int>temp(n);
    vector<int>bar(10);
    vector<int>count(10);
    int maxDigit = 1;
    int pos = 10;
    for (int i = 0; i < n; ++i)
    {
        cin >> nums[i];
        while (nums[i] >= pos)
        {
            maxDigit++;
            pos *= 10;
        }
    }
    pos = 10;
    for (int i = 0; i < maxDigit; ++i)
    {
        //全部元素装入桶里
        for (int j = 0; j < n; ++j)
        {

            bar[(nums[j]/(pos/10)) % 10]++;
        }
        //计算count数组
        count[0] = bar[0];
        for (int j = 1; j < 10; ++j)
        {
            count[j] = bar[j] + count[j - 1];

        }
        //将按位排好的元素装入到一个临时容器中
        for (int j = n - 1; j >= 0; --j)
        {
            temp[count[(nums[j] / (pos / 10)) % 10]-1] = nums[j];
            count[(nums[j] / (pos / 10)) % 10]--;
        }

        nums.assign(temp.begin(),temp.end());
        bar.assign(10, 0);
        pos *= 10;
    }
    for (int i = 0; i < n; ++i)
    {
        cout << nums[i] << " ";
    }
    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值