数据结构——排序

排序

简单排序

  1. 选择排序
  2. 冒泡排序
  3. 插入排序

选择排序

排序思想:

  1. 将排序序列分为已经有序和待排序两部分
  2. 每次从待排序的序列中选出最小的放到已排序末尾

性质:不稳定

void sort1(int a[], int n)
{
	for (int i = 0; i < n - 1; i ++ ){ //选择n-1次
		int min_id = i;		//默认当前待排序的第一个为最小
		for (int j = i; i < n; j ++ )
			if (a[j] < a[min_id])
				min_id = j;
		//找到最小值, 交换:
		swap(a[i], a[min_id]);
	}
}

冒泡排序

排序思想:
反复比较两两相邻元素,若不符合顺序要求,则交换相邻元素,直至有序

性质: 稳定

void sort2(int a[], int n)
{
	for (int i = 0; i < n - 1; i ++ ){
		int flag = 1;
		for (int j = 0; j < n - i - 1; j ++ )
			if (a[j] > a[j + 1])
				swap(a[j], a[j + 1]), flag = 0;
		if (flag)
			break;
	}
}

插入排序

排序思想:

  1. 将序列分为待排序和已排序两部分
  2. 每次从待排序的部分选择一个插入到已排序部分(这里采用不断向前渗透的方法)
void sort3(int a[], int n)
{
	for (int i = 2; i <= n; i ++ ){
		a[0] = a[i];
		for (int j = i; a[j] < a[j - 1]; j -- )
			swap(a[j], a[j - 1]);
	}
}

先进排序

快速排序

排序思想:

  1. 对待排序序列进行划分
  2. 对前半部分排序
  3. 对后半部分排序

性质:不稳定

划分:
从序列中选择一个元素作为划分依据,将序列分为前后两部分

//划分:
int Part(int a[], int l, int r)
{
	int tmp = a[l];
	while (l < r){
		while (l < r && a[r] >= tmp)
			r --;
		a[l] = a[r];
		while (l < r && a[l] <= tmp)
			l ++;
		a[r] = a[l];
	}
	a[l] = tmp;
	return l;
}

//排序:
void sort3(int a[], int l, int r)
{
	if (l >= r)
		return;
	int k = Part(a, l, r);
	sort3(a, l, k - 1);
	sort3(a, k + 1, r);
	return;
}

堆排序

堆:完全二叉树
大顶堆:父节点的值大于等于子节点的值
小顶堆: 父节点的值小于等于子节点的值

堆调整

void Aheap(int s, int n)
{
    int i = s;
    while (2 * i + 1 < n){
        int j = 2 * i + 1;
        if (j + 1 < n && heap[j + 1] > heap[j]) j ++;

        if (heap[i] >= heap[j]) break;

        swap(heap[i], heap[j]);

        i = j;

    }

}

建堆

void Build(int n)
{
	for (int i = n / 2 - 1; i >= 0; i -- )
		Aheap(i, n);
}

排序

void HeapSort(int n)
{
	Build(n);
	
	for (int i = n - 1; i > 0; i -- ){
		swap(heap[0], heap[i]);
		Aheap(0, i);
	}
}
posted @ 2022-01-05 19:50  lhqwd  阅读(45)  评论(0)    收藏  举报