zoukankan      html  css  js  c++  java
  • 常用排序算法小结

    1. 直接插入排序
      其思想为:可以先取出第一个作为有序区间,遍历剩下的无序区间,找到待排序元素依次和有序区间比较插入,直到整个数组排序完成,其时间复杂度为o(n^2),具体实现如下

       #include <stdio.h>
       void insert(int a[], int n) {
       	int i, j, x;
       	for (i = 1; i < n; i++) {
       		x = a[i];
       		for (j = i - 1; j > -1 && a[j] > x; a[j+1] = a[j], j--);
       		a[j+1] = x;
       	}
       	
       	for (i = 0; i < n; i++) {
       		printf("%2d", a[i]);
       	}
       } 
      
       int main (void) {
       	//直接插入排序,排序思想:遍历无序区间,找出排序元素
       	int a[6] = {3, 5, 4, 6, 2, 7};
       	insert(a, 6);	//2, 3, 4, 5, 6, 7
       }
      
    2. 直接选择排序
      其思想为:每次从无序区间中找到最小值和无序区间的第一个值进行交换,遍历整个无序区间,直到无序区间只剩一个值(初始有序区间为空,无序区间为整个待排序数组)

       #include <stdio.h>
      
       void select(int a[], int n) {
       	int i, j, k, t;
       	for (i = 0; i < n-1; i++) {
       		k = i;
       		for (j = i+1; j < n; j++) {
       			if (a[j] < a[k]) {
       				k = j;
       			}
       		}
       		if (k - i) {
       			t = a[k];
       			a[k] = a[i];
       			a[i] = t;
       		}
       	}
       	
       	for (i = 0; i < n; i++) {
       		printf("%2d", a[i]);
       	}
       }
      
       int main (void) {
       	int a[6] = {3, 5, 6, 4, 2, 7};
       	select(a, 6); //2, 3, 4, 5, 6, 7
       }
      
    3. 冒泡排序
      排序思想:经过n-1趟排序,每一趟找出最小值到冒泡最终的位置,其时间复杂度为o(n^2), 结束的标志为某一趟未经过任何排序,则可认为排序完成

       #include <stdio.h>
      
       void babel(int a[], int n) {
       	int i, j, t, tag = 1;
       	for (i = 0; i < n-1 && tag; i++) {
       		tag = 0;
       		for (j = n-1; j > i; j--) {
       			if (a[j] < a[j-1]) {
       				tag = 1;
       				t = a[j];
       				a[j] = a[j-1];
       				a[j-1] = t;
       			}
       		}
       	}
       	
       	for (i = 0; i < n; i++) {
       		printf("%2d", a[i]);
       	}
       }
      
       int main(void) {
       	int a[6] = {3, 5, 4, 6, 2, 7};
       	babel(a, 6);
       }
      
    4. 快速排序
      排序思想:分治,使用递归将问题分解。取出第一个元素作为基准元素(这里取任何元素都可以,以第一个元素为例,且为从小到大排序),从后往前寻找比基准元素小的元素排在左边,从前往后寻找比基准元素大的元素排在右边,左递归右递归,实现元素的排序。具体C代码如下:

       #include <stdio.h>
      
       int my_sort(int a[], int left, int right) {
       	int temp, i, j;
       	temp = a[left];
       	for (i = left, j = right-1; i < j;) {
       		for (; (i < j) && (a[j] >= temp); j--);  //找出比temp小的元素 
       		if (i < j) {
       			a[i] = a[j];
       		} 
       		for (; (i < j) && (a[i] < temp); i++);	//找出比temp大的元素 
       		if (i < j) {
       			a[j] = a[i];
       		}
       	}
       	
       	a[i] = temp;
       	return i;
       }
      
       void quick(int a[], int left, int right) {
       	int mid = -1;
       	if (a && left < right) {
       		mid = my_sort(a, left, right);
       		quick(a, left, mid);	//左边递归 
       		quick(a, mid+1, right);	//右边递归 
       	}
       
       }
      
       int main(void) {
       	int a[8] = {5, 6, 2, 3, 4, 1, 7, 8};
       	quick(a, 0, 9);
       	
       	for (int i = 0; i < 8; i++) {
       		printf("%2d", a[i]);
       	}
       	return 0;
       }
      
       //1, 2, 3, 4, 5, 6, 7, 8
      

      当然,作为一名前端工程师(不知道够格不,继续努力好了),有必要用Javascript语言来展示一下这个应用十分广泛的排序方法,不关乎语言的不同,思想上是等同的,只是其中某些方法我们可以直接调用。当然,这也是我面试时被问到的,有必要总结一下。

       var quickSort = function (arr) {
       	if (arr.length <= 1) {
       		return arr;
       	}
       	var left = [];		//左边的数组
       	var right = [];		//右边的数组
       	var index = Math.floor(arr.length/2);
      
       	for (var i = 0, len = arr.length; i < len; i++) {
       		if (i - index) {
       			if (arr[i] < arr[index]) {
       				left.push(arr[i]);
       			} else {
       				right.push(arr[i]);
       			}
       		}
       	}
      
       	return quickSort(left).concat(arr[index], quickSort(right));
      
       };
      
       console.log(quickSort([5, 6, 2, 3, 4, 1, 7, 8]));
       //1, 2, 3, 4, 5, 6, 7, 8
      
    5. 归并排序
      排序思想:依然是分治啦,结合我们的递归。这个排序方法我还回忆了半天,谁叫我好久都没碰过C语言了勒。感觉主要的点在于对数组的左右两个区间合并过程。

       #include <stdio.h>
      
       //合并排序的过程,拆开看就是将两个无序数组合并成一个升序序列
       void Result(int a[], int x, int y) {
       	int b[200];	//定义的尽量大吧
       	int i, j, k;
       	i = x;
       	j = (x+y)/2;
       	k = 0;
       	while(i < (x+y)/2 || j < y) {
       		if (j == y || (i < (x+y)/2 && a[i] < a[j])) {
       			b[k++] = a[i++];
       		} else {
       			b[k++] = a[j++];
       		}
       	}
       	
       	for (i = x; i < j; i++) {
       		a[i] = b[i-x];
       	} 
       }
      
       void mergeSort(int a[], int x, int y) {
       	if (y - x > 1) {
       		mergeSort(a, x, (x+y)/2);
       		mergeSort(a, (x+y)/2, y);
       		Result(a, x, y);
       	}
       }
      
       int main(void) {
       	int a[9] = {8, 6, 5, 3, 9, 7, 4, 2, 1};
       	mergeSort(a, 0, 9);
       	for (int i = 0; i < 9; i++) {
       		printf("%2d", a[i]);
       	}
       	//1, 2, 3, 4, 5, 6, 7, 8, 9
       	return 0;
       }
      

      暂时总结的排序方法就这几个了,可能自己去画图,手动跟踪运行会理解的更加深刻。

  • 相关阅读:
    [公告] 置顶博客一览
    [公告] 关于花
    【题解】[SNOI2019] 纸牌
    [题解向] PAM简单习题
    [题解向] 带悔贪心泛做
    [题解向] Manacher简单习题
    java记录(2)
    java记录(1)
    js垃圾回收的机制
    盒子的计算
  • 原文地址:https://www.cnblogs.com/susantong/p/6560998.html
Copyright © 2011-2022 走看看