zoukankan      html  css  js  c++  java
  • 十个经典排序算法

    十个经典排序算法

    快排

    /* 快速排序 */
    #include <iostream>
    #include <cstdlib>
    
    #define N 6
    
    using namespace std;
    
    void quick_sort(int arr[], int begin, int end);
    void print_arr(int arr[], int n);
    
    int main()
    {
    	int arr[N] = {10, 4,7, 10, 4,7};
    	cout << "排序前:" << endl;
    	print_arr(arr, N);
    	quick_sort(arr, 0, N);
    	cout << "排序后:" << endl;
    	print_arr(arr, N);
    }
    
    // 不包含 end 
    void quick_sort(int arr[], int begin, int end)
    {
    	if (end - begin <= 1)
    		return;
    	swap(arr[begin], arr[(begin + end) / 2]);
    	int pivot = arr[begin];
    	int i = begin + 1;
    	int j = end - 1;
    	while (i < j)
    	{
    		while (i < end - 1 && arr[i] < pivot)
    			i++;
    		while (j > begin && arr[j] > pivot)
    			j--;
    		if (i < j)
    			swap(arr[i], arr[j]);
    	}
    	if (j < i)
    		swap(arr[j], arr[begin]);
    	quick_sort(arr, begin, j);
    	quick_sort(arr, j + 1, end);
    }
    
     
    void print_arr(int arr[], int n)
    {
    	for (int i = 0; i < n; i++)
    		cout << arr[i] << " ";
    	cout << endl;
    }
    

    快排的要点

    i 和 j 的关系

    当 i < j 时,才能进行循环的移动和交换

    每次让 i 指向从左到右,大于 pivot 的数

    每次让 j 指向从右到左,小于 pivot 的数

    当循环结束时,j 有两种情况,一种是 等于 i 一种是 小于 i

    如果 j == i 的话,那么说明此时已经是有序了,不用再进行调换,如果调换反而会打乱顺序

    如果 j < i 的话,说明 j 指向的是最后一个小于 pivot 的数,让他们换个位置

    归并排序

    /*归并排序*/
    #include <iostream>
    #include <cstdlib>
    #include <string>
    
    #define N 10
    
    using namespace std;
    
    void merge_sort(int arr[], int begin, int end); 
    void print_arr(int arr[], int n);
    
    int main()
    {
    	int arr[N] = {1,2,1,1,2,1,1,2,1,87};
    	cout << "排序前:" << endl;
    	print_arr(arr, N);
    	merge_sort(arr, 0, N);
    	cout << "排序后:" << endl;
    	print_arr(arr, N);
    }
    
    void merge_sort(int arr[], int begin, int end)
    {
    	if (end - begin <= 1)
    		return;
    	int * new_arr = new int[end - begin];
    	merge_sort(arr, begin, (begin + end) / 2);
    	merge_sort(arr, (begin + end) / 2, end);
    	int i = begin;
    	int j = (begin + end) / 2;
    	int k = 0;
    	while (i < (begin + end) / 2 && j < end)
    		new_arr[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
    	while (i < (begin + end) / 2)
    		new_arr[k++] = arr[i++];
    	while (j < end)
    		new_arr[k++] = arr[j++];
    	while (k)
    		arr[begin + k - 1] = new_arr[--k];
    	delete new_arr;
    }
    
     
    void print_arr(int arr[], int n)
    {
    	for (int i = 0; i < n; i++)
    		cout << arr[i] << " ";
    	cout << endl;
    }
    

    归并排序主要要注意的就是要造个新数组,把两个已经有序的子数组依次按从小到大放到新数组里面

    计数排序

    /* 计数排序 */
    #include <iostream>
    #include <cstdlib>
    
    #define N 10
    
    
    using namespace std;
    
    void count_sort(int arr[], int n); 
    void print_arr(int arr[], int n);
    
    int main()
    {
    	int arr[N] = {5,4,3,2,1,5,4,3,2,1};
    	cout << "排序前:" << endl;
    	print_arr(arr, N);
    	count_sort(arr, N);
    	cout << "排序后:" << endl;
    	print_arr(arr, N);
    }
    
    void count_sort(int arr[], int n)
    {
    	int max = arr[0];
    	for (int i = 0; i < n; i++)
    		if (arr[i] > max)
    			max = arr[i];
    	int * count = (int * )calloc(max + 1, sizeof(int));	// count 数组存放 0-max 每个数出现的次数
    	
    	for (int i = 0; i < n; i++)
    		count[arr[i]]++;
    	
    	for (int i = 1; i <= max; i++)
    		count[i] += count[i-1];
    	
    	int curr = 0;
    	int i = 0;
    	while (curr <= max)
    	{
    		while (count[curr] > i)
    			arr[i++] = curr;
    		curr++;
    	}
    	
    }
    
     
    void print_arr(int arr[], int n)
    {
    	for (int i = 0; i < n; i++)
    		cout << arr[i] << " ";
    	cout << endl;
    }
    

    希尔排序

    希尔排序的稳定性_百度知道 (baidu.com)

    /* shell 排序 */
    
    #include <iostream>
    #include <cstdlib>
    
    #define N 3
    
    using namespace std;
    
    void shell_sort(int arr[], int n); 
    void print_arr(int arr[], int n);
    void bubble_sort(int arr[], int n, int begin, int step);
    
    int main()
    {
    	int arr[N] = {1,2,0};
    	cout << "排序前:" << endl;
    	print_arr(arr, N);
    	shell_sort(arr, N);
    	cout << "排序后:" << endl;
    	print_arr(arr, N);
    }
    
    void shell_sort(int arr[], int n)
    {
    	for (int step = n/2; step > 0; step /= 2)
    		for (int i = 0; i < step; i++)
    			bubble_sort(arr, n, i, step);
    	
    }
    
    void print_arr(int arr[], int n)
    {
    	for (int i = 0; i < n; i++)
    		cout << arr[i] << " ";
    	cout << endl;
    } 
    
    void bubble_sort(int arr[], int n, int begin, int step)
    {
    	bool changed = false;
    	for (int i = begin; i < n; i += step)
    	{
    		changed = false;
    		for (int j = begin; j < n - step; j += step)
    		{
    			if (arr[j] > arr[j + step])
    			{
    				int temp = arr[j + step];
    				arr[j + step] = arr[j];
    				arr[j] = temp;
    				changed = true;
    			}
    		}
    		if (!changed)
    			break;
    	}
    }
    

    堆排序

    【算法】排序算法之堆排序 - 知乎 (zhihu.com)

    堆排序很好

    /* 堆排序 */
    #include <iostream>
    #include <cstdlib>
    
    #define N 12
    
    using namespace std;
    
    void heap_sort(int arr[], int n); 
    void print_arr(int arr[], int n);
    void heapify(int arr[], int n);
    
    int main()
    {
    	int arr[N] = {5,4,3,2,1,5,4,7,8,3,2,1};
    	cout << "排序前:" << endl;
    	print_arr(arr, N);
    	heap_sort(arr, N);
    	cout << "排序后:" << endl;
    	print_arr(arr, N);
    }
    
    void heap_sort(int arr[], int n)
    {
    	heapify(arr, n);
    	for (int i = n; i > 1; i--)
    	{
    		swap(arr[i - 1], arr[0]);
    		heapify(arr, i - 1);
    	}
    }
    
    //完全二叉树 编号从1开始 
    void heapify(int arr[], int n)
    {
    	for (int i = 2; i <= n; i++)
    		for (int j = i; j > 1; j /= 2)
    			if (arr[j - 1] > arr[j/2 - 1])
    				swap(arr[j - 1], arr[j/2 - 1]);
    }
     
    void print_arr(int arr[], int n)
    {
    	for (int i = 0; i < n; i++)
    		cout << arr[i] << " ";
    	cout << endl;
    }
    

    桶排序

    【算法】排序算法之桶排序 - 知乎 (zhihu.com)

    桶排序算法 (biancheng.net)

    基数排序(需要先修桶排序)

    【算法】排序算法之基数排序 - 知乎 (zhihu.com)

  • 相关阅读:
    execvp
    Linux系统调用getrlimit()与setrlimit()函数详解
    Va_start及Vsprintf应用
    waitpid()
    sdut 2408 Pick apples 夜
    poj 1273 Drainage Ditches 夜
    poj 1408 Fishnet 夜
    poj 1113 Wall 夜
    poj 1584 A Round Peg in a Ground Hole 夜
    poj 3007 Organize Your Train part II 夜
  • 原文地址:https://www.cnblogs.com/studentWangqy/p/15491780.html
Copyright © 2011-2022 走看看