常见排序算法的思想及实现

冒泡排序

每一趟排序(包括多次两两比较和交换)找出余下的最大元素放在数组的最后,叫沉底排序更贴切。

void bubble_sort(int a[], int len)
{
	int i, j;
	for(i = 0; i < len - 1; i++)//len - 1趟排序
	{
		for (j = 0; j < len - i - 1; j++)//从第一趟排序,推出j的范围
		{
			if(a[j] > a[j + 1])//前面的元素更大需要往下沉
			{
				swap(&a[j], &a[j + 1]);
			}
		}
	}
}

 

选择排序

 

每一趟排序找出余下元素中最小的元素放在数组的最前面

void select_sort(int a[], int len)
{
	int i, j;
	for(i = 0; i < len - 1; i++)//len - 1趟排序
	{
		for(j = i + 1; j < len; j++)//一趟中需要和a[i]比较的元素
		{
			if(a[i] > a[j])
			{
				swap(&a[i], &a[j]);
			}
		}
	}
}

void select_sort_plus(int a[], int len)
{
	int i, j, min;
	for(i = 0; i < len - 1; i++)//len - 1趟排序
	{
		min = i;
		for(j = i + 1; j < len; j++)//选择排序改进:标记最小值,一趟最多交换一次
		{
			if(a[min] > a[j])
			{
				min = j;
			}
		}
		if(min != i)
		{
			swap(&a[i], &a[min]);
		}
	}
}

 

插入排序

 

每一趟排序把本次排序的元素往前插入到合适的位置

void insert_sort(int a[], int len)
{
	int i, j;
	for(i = 1; i < len; i++)
	{
		for(j = i; j > 0 && a[j] < a[j - 1]; j--)
		{
			swap(&a[j], &a[j - 1]);
		}
	}
}

 

希尔排序

 

插入排序的改进;插入排序比较移动的步长是1,希尔排序中改进该步长,从大缩小到1

void shell_sort(int a[], int len)
{
	int i, j, k = 1;
	while(k < len / 3)
	{
		k = 3 * k + 1;
	}
	while(k >= 1)
	{
		for(i = k; i < len; i++)
		{
			for(j = i; j >= k && a[j] < a[j - k]; j -= k)
			{
				swap(&a[j], &a[j - k]);
			}
		}
		k /= 3;
	}
}

 

快速排序

 

每趟排序把基准值放到对的位置即左边的元素都比它小,右边的元素都比它大

void quick_sort(int a[], int low, int high)
{
	int pivot;
	if(low < high)
	{
		pivot = quickSort(a, low, high);
		quick_sort(a, low, pivot - 1);
		quick_sort(a, pivot + 1, high);
	}
}

int quickSort(int a[], int low, int high)
{
	int pivot = a[low];
	while(low < high)
	{
		while(low < high && pivot <= a[high])
			high--;
		swap(&a[low], &a[high]);
		while(low < high && pivot >= a[low])
			low++;
		swap(&a[low], &a[high]);
	}
	return low;
}

 

堆排序

 

利用大顶堆的特点:根的值比左右子树都大

先构造堆

交换堆的第一个元素和最后一个元素,使最大的元素放在数组的最后,再对前面的堆进行调整,重复该操作

void sink(int a[], int root, int length)
{
    int left = 2 * root + 1;
    while (left < length) {
        int bigger = left;
        int right = left + 1;
        if (right < length && a[right] > a[left]) bigger = right;
        if (a[root] < a[bigger]) {
            swap(a[root], a[bigger]);
            root = bigger;
            left = 2 * root + 1;
        } else {
            break;
        }
    }
}

void build_heap(int a[], int length)
{
    for (int i = (length - 2) / 2; i >= 0; --i) {
        sink(a, i, length);
    }
}

void heap_sort(int a[], int length)
{
    build_heap(a, length);
    for (int i = length - 1; i >= 1; --i) {
        swap(a[i], a[0]); // 每次把堆顶元素(剩下的最大元素)放到正确的位置
        sink(a, 0, i); // [0, i) 以 a[0]为root的堆,除了a[0] [1, i)是OK的堆顺序,sink a[0] 调整堆
    }
}

 

归并排序

 

递归地合并两个有序数组

void merge_sort(int a[], int len)
{
	int *temp = (int *) malloc(len * sizeof(int));
	mergeSort(a, 0, len - 1, temp);
	free(temp);
}

void mergeSort(int a[], int low, int high, int temp[])
{
	int mid = (low + high) / 2;
	if(low < high)
	{
		mergeSort(a, low, mid, temp);
		mergeSort(a, mid + 1, high, temp);
		mergeArray(a, low, mid, high, temp);
	}
}

void mergeArray(int a[],int low, int mid, int high, int temp[])
{
	int i = low, j = mid + 1, k = 0;
	while(i <= mid && j <= high)
	{
		if(a[i] < a[j])
		{
			temp[k++] = a[i++];
		}
		else
		{
			temp[k++] = a[j++];
		}
	}
	while(i <= mid)
	{
		temp[k++] = a[i++];
	}
	while(j <= high)
	{
		temp[k++] = a[j++];
	}
	for(i = 0; i < k; i++ )
	{
		a[low + i] = temp[i];
	}
}

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页