数据结构-----排序

归并排序

将待排序的元素序列分成两个长度相等的子序列,对每一个子序列排序,然后将他们合并成一个序列。

划分

归并

void mergesort(int* a, int begin, int end, int* tmp)//归并排序
{
	assert(a);
	if (begin >= end)
	{
		return;
	}
	int mid = begin +((end - begin) >> 1);
	mergesort(a, begin, mid, tmp);
	mergesort(a, mid + 1, end, tmp);
	mergesort(a, begin, mid, mid + 1, end, tmp);
}

时间复杂度:最优情况:O(NlgN)

                      最差情况:O(NlgN)

空间复杂度:O(N),是一种稳定的算法

选择排序

从n个数中选择一个最小的数放到数组的第一个位置上,在从剩下n-1个数中选出最小数,放到开头,依次进行下去,知道剩下最后一个元素即为最大数,放到最后位置。

void swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
void selectsort(int* a, int n)//选择排序
{
	assert(a);
	int begin = 0;
	int end = n - 1;
	while (begin <= end)
	{
		int min = begin;
		int max = begin;
		for (int i = begin; i <= end; i++)
		{
			if (a[i] > a[max])
				max = i;
			if (a[i] < a[min])
				min = i;
		}
		swap(&a[begin], &a[min]);
		swap(&a[end], &a[max]);
		++begin;
		--end;
	}
}

时间复杂度:最优情况:O(n^2)

                      最差情况:O(n^2)

空间复杂度:O(1),是一种不稳定的算法

快速排序

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置为止。

void swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int quicksort(int* a, int begin, int end,int n)//快速排序
{
	assert(a);
	int key = a[end];
	int keyindex = 0;
	begin = 0;
    end = n - 1;
	while (begin < end)
	{
		while (begin < end&&a[begin] <= key)
		
			++begin;
	
		while (begin < end&&a[begin] >= key)
		
			--end;
		
		swap(&a[begin], &a[end]);
	}
  swap(&a[begin], &a[end]);
  return begin;
}

 时间复杂度:最优情况:O(nlgn)

                      最差情况:O(n^2)

空间复杂度:O(lgn),是一种不稳定的算法

插入排序

基本思想:

每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的合适位置上,直到元素全部插完为止。

void insertsort(int* a,int n)//插入排序
{
	assert(a);
	int i = 0;

	for (i = 0; i < n-1; i++)
	{
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0 && a[end] > tmp)
		{
			a[end + 1] = a[end];
			--end;
		}
		a[end + 1] = tmp;
	}
}

时间复杂度:最优情况:O(n)

                      最差情况:O(n^2)

空间复杂度:O(1),是一种稳定的算法

堆排序

堆排序就是把最大堆堆顶的最大数取出,将剩余的堆继续调整为最大堆,再次将堆顶的最大数取出,这个过程持续到剩余数只有一个时结束。在堆中定义以下几种操作:

  • 最大堆调整(Max-Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  • 创建最大堆(Build-Max-Heap):将堆所有数据重新排序,使其成为最大堆
  • 堆排序(Heap-Sort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

继续进行下面的讨论前,需要注意的一个问题是:数组都是 Zero-Based,这就意味着我们的堆数据结构模型要发生改变

/**
 * 从 index 开始检查并保持最大堆性质
 *
 * @array
 *
 * @index 检查的起始下标
 *
 * @heapSize 堆大小
 *
 **/
function maxHeapify(array, index, heapSize) {
  var iMax = index,
      iLeft = 2 * index + 1,
      iRight = 2 * (index + 1);
  if (iLeft < heapSize && array[index] < array[iLeft]) {
    iMax = iLeft;
  }
  if (iRight < heapSize && array[iMax] < array[iRight]) {
    iMax = iRight;
  }
  if (iMax != index) {
    swap(array, iMax, index);
    maxHeapify(array, iMax, heapSize); // 递归调整
  }
}
function swap(array, i, j) {
  var temp = array[i];
  array[i] = array[j];
  array[j] = temp;
}

时间复杂度:最优情况:O(nlgn)

                      最差情况:O(nlgn)

空间复杂度:O(1),是一种不稳定的算法

希尔排序

是插入排序的一种优化

时间复杂度:最优情况:O(n)

                      最差情况:O(n^2)

空间复杂度:O(1),是一种不稳定的算法

void xiersort(int* a, int n)//希尔排序
{
	assert(a);
	int gap = 3;
	int i = 0;
	while (gap > 0)
	{
		gap = gap / 2;
		for (i = 0; i <n - gap; i++)
		{
			int end = i;
			int tmp = a[end + 1];
			while (end >= 0 && a[end] > tmp)
			{
				a[end + gap] = a[end];
				--end;
			}
			a[end + gap] = tmp;
		}
	}
}

冒泡排序

相邻元素进行比较,第一趟完,就把最大的放到数组的最后位置,在比较剩下的n-1个元素,把这n-1个数中最大数放到倒数第二的位置,依次进行,直到剩最后一个元素,就是最小的元素。

时间复杂度:最优情况:O(n)

                      最差情况:O(n^2)

空间复杂度:O(1),是一种稳定的算法

void maopaosort(int* a, int n)//冒泡排序
{
	assert(a);
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n - 1 - i; j++)
		{
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42365095/article/details/82909049
今日推荐