关于对常见的几种排序的理解。

排序这个东西是我们经常要用到的,下面谈一谈我对排序的理解。

(1)插入排序:插入排序是指先将元素的第一个数当做一个有序的表,然后把第二个元素与第一个元素之间进行比较,插入最开始有序表中,从第二个元素开始,每一个元素都与前面的有序表比较,并加入这个有序表。最后得到一个完全有序的序列。

         因为在比较过程中,如果待插入的元素如果与有序表中的某个元素相比,是相等的。那么这个元素就插入在后面,所以插入排序是稳定的。时间复杂度:O(n^2),其他插入排序:2分插入

执行的效果如下图:

// 插入排序
var arr = [1, 4, 5, 7, 3, 2];
function insertSort(arr, length) {
  var temp;
  for (var i= 0; i < length; i++) {
    if (arr[i]>arr[i+1]) {
      temp = arr[i+1];
      for (var j=i;j>=0&&temp<arr[j];j--){
        console.log(123)
        arr[j+1]=arr[j];
      }
      arr[j+1]=temp
    }
  }
  return arr;
}
console.log(insertSort(arr, arr.length))




(2)希尔排序:希尔排序是插入排序的改进,希尔排序按照一个给定的2k,k,k/2...1这样的数来将一堆需要排序的数划分成几个子序列,进行插入排序,然后再将一个基本有序的序列,再进行直接插入排序。

       比如说给定一个序列 1 7 6 5 9 2 0 以2划分子序列是 1 5 0,7 9,6 2,对这三个子序列分别进行插入排序,最后再进行直接插入排序。因为在子序列的直接插入过程中,很可能会造成一个数据与另一个子序列中的数据相同,但是却改变了位置,所以希尔排序是一个不稳定的排序。

// 插入排序
void ShellSort(int arr[], int length)
{
	int increasement = length;
	int i, j, k;
	do
	{
		// 确定分组的增量
		increasement = increasement / 3 + 1;
		for (i = 0; i < increasement; i++)
		{
			for (j = i + increasement; j < length; j += increasement)
			{
				if (arr[j] < arr[j - increasement])
				{
					int temp = arr[j];
					for (k = j - increasement; k >= 0 && temp < arr[k]; k -= increasement)
					{
						arr[k + increasement] = arr[k];
					}
					arr[k + increasement] = temp;
				}
			}
		}
	} while (increasement > 1);
}

(3)堆排序:堆其实就是一个完全二叉树,而且必须满足根节点必须大于等于子节点或者小于等于孩子节点。

堆排序分成两个过程:

      第一个过程是构建最大堆或者最小堆。一个排序后祖先节点就是最大的数或者最小的数。

      第二个过程就是排序了,将第一个过程得到祖先节点存入数组中,然后将最后一个叶子节点换到第一个过程得到的祖先节点上,再进行构造最大堆或者最小堆,依次这样直到剩下最后一个叶子节点。

      堆排序是不稳定的排序

(4)选择排序:选择排序是指在一个给定的序列中,如果是从小到大排序,首先选择一个最小的数与第一个数交换,然后从第二个数到最后一个数中选择一个最小的数与第二个数交换,依次进行,直到n-1个元素与第n个元素比较。

        选择排序是不稳定的排序。

// 选择排序
var arr = [1, 4, 5, 7, 3, 2];
function selectionSort(arr, length) {
  var temp;
  for (var i= 0; i < length; i++) {
    for (var j = i; j < length - 1; j++) {
      if (arr[j] > arr[j+1]) {
        temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
    if (arr[j] >= arr[i]) {
      temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
    }
    console.log(arr[j])
  }
  return arr;
}
console.log(selectionSort(arr, arr.length))

 

(5)快速排序:这个排序是目前非常火的一个排序,当序列是分布随机的,用快速排序的平均时间是最快的。当排序的数特别大,比如从10000个数中选取最小的十个时用堆排序。

快速排序的思想是给定一个序列,给定两个游标i,j分别指向序列的头和尾(假设以升序排列)。(1)让i和j指向的数进行比较,如果不发生交互,j向后走1,如果一直不发生交换,则j与i重合,则这一趟排序将待排序的序列分成了左右两个部分----i后面的元素都比i大,如果发生交换,则i+1,然后与j比较,如果又发生交换,j-1,直到i,j重合,一趟排序完毕。

快速排序是不稳定的排序。

void QuickSort(int arr[], int start, int end)
{
	if (start >= end)
		return;
	int i = start;
	int j = end;
	// 基准数
	int baseval = arr[start];
	while (i < j)
	{
		// 从右向左找比基准数小的数
		while (i < j && arr[j] >= baseval)
		{
			j--;
		}
		if (i < j)
		{
			arr[i] = arr[j];
			i++;
		}
		// 从左向右找比基准数大的数
		while (i < j && arr[i] < baseval)
		{
			i++;
		}
		if (i < j)
		{
			arr[j] = arr[i];
			j--;
		}
	}
	// 把基准数放到i的位置
	arr[i] = baseval;
	// 递归
	QuickSort(arr, start, i - 1);
	QuickSort(arr, i + 1, end);
}

(6)归并排序:把一个序列分成两个或两个以上的多个子序列,分别将各个子序列排列有序,然后合并成一个有序序列。


void MergeSort(int arr[], int start, int end, int * temp)
{
	if (start >= end)
		return;
	int mid = (start + end) / 2;
	MergeSort(arr, start, mid, temp);
	MergeSort(arr, mid + 1, end, temp);
 
	// 合并两个有序序列
	int length = 0; // 表示辅助空间有多少个元素
	int i_start = start;
	int i_end = mid;
	int j_start = mid + 1;
	int j_end = end;
	while (i_start <= i_end && j_start <= j_end)
	{
		if (arr[i_start] < arr[j_start])
		{
			temp[length] = arr[i_start]; 
			length++;
			i_start++;
		}
		else
		{
			temp[length] = arr[j_start];
			length++;
			j_start++;
		}
	}
	while (i_start <= i_end)
	{
		temp[length] = arr[i_start];
		i_start++;
		length++;
	}
	while (j_start <= j_end)
	{
		temp[length] = arr[j_start];
		length++;
		j_start++;
	}
	// 把辅助空间的数据放到原空间
	for (int i = 0; i < length; i++)
	{
		arr[start + i] = temp[i];
	}
}

(7)冒泡排序

       首先从数组的第一个元素开始到数组最后一个元素为止,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置,此时数组最右端的元素即为该数组中所有元素的最大值。接着对该数组剩下的n-1个元素进行冒泡排序,直到整个数组有序排列。算法的时间复杂度为O(n^2)。

附上冒泡排序JavaScript实现方法:

// 冒泡排序
var arr = [1, 4, 5, 7, 3, 2];
function bubbleSort(arr, length) {
  var temp;
  for (var i= 0; i < length; i++) {
    var flag = 0;
    for (var j = 0; j < length - i - 1; j++) {
      if (arr[j] > arr[j+1]) {
        temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
        flag = 1;
      }
    }
    if (!flag) {
      break;
    } 
  }
  return arr;
}
console.log(bubbleSort(arr, arr.length))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值