之前一直有想法,搭一个独立博客,记录一下学习所得,顺便分享一些旅途中的经历,却一直没有下定决心。想着很多原来学习过程中总结过的东西,后来慢慢都丢了,未免有些遗憾。其实前几年还是挺喜欢写文章的,大都发布在各种社交网络,渐渐荒废。域名挑了个 lambda, 一则,这是希腊希腊字母,多年过去,我还是喜欢个性;二则,lambda象形所代表的孤独,低调,正应了了我的追求。是以为域名。
完整代码:
void BubbleSort(int *list, int len) {
int i, j, temp;
int flag = 1;
for(i = 0; i < len && flag; i++) {
flag = 0;
for(j = len; j > i; j--) {
if(list[j-1] > list[j]) {
temp = list[j-1];
list[j-1] = list[j];
list[j] = temp;
flag = 1;
}
}
}
}
完整代码:
void SelectSort(int *list, int len) {
int i, j, temp, min;
for(i = 0; i < len; i++) {
min = i;
for(j = i+1; j < len; j++) {
if(list[j] < list[min]) {
min = j;
}
}
if(i != min) {
temp = list[i];
list[i] = list[min];
list[min] = temp;
}
}
}
完整代码:
void InsertSort(int *list, int len) {
int i, j, temp;
for(i = 1; i < len; i++) {
if(list[i] < list[i-1]) {
temp = list[i];
for(j = i-1; j >= 0 && list[j] > temp; j--)
list[j+1] = list[j];
list[j+1] = temp;
}
}
}
完整代码:
void ShellSort(int *list, int len) {
int i, j, temp, gap;
for(gap = len / 2; gap > 0; gap /= 2)
for(i = 0; i < gap; i++) {
for(j = gap; j < len; j+=gap)
if(list[j] < list[j-gap]) {
int temp = list[j];
int k = j - gap;
while(k >= 0 && list[k] > temp) {
list[k + gap] = list[k];
k -= gap;
}
list[k + gap] = temp;
}
}
}
void MinHeapFixup(int *list, int i) {
int j = (i - 1) / 2;
int temp = list[i];
while(j >= 0 && i != 0) {
if(list[j] <= temp)
break;
list[i] = list[j];
i = j;
j = (i - 1) / 2;
}
list[i] = temp;
}
按定义,每次都只能删除第0个数据。为了便于重建堆,将最后一个数据的值赋给根结点,然后再从根结点开始进行一次 从上向下的调整。调整时先在左右儿子结点中找最小的,如果父结点比这个最小的子结点还小说明不需要调整了,反之 将父结点和它交换后再考虑后面的结点。相当于从根结点将一个数据的“下沉”过程。
void MinHeapFixdown(int a[], int i, int n)
{
int j, temp;
temp = a[i];
j = 2 * i + 1;
while (j < n)
{
if (j + 1 < n && a[j + 1] < a[j])
j++;
if (a[j] >= temp)
break;
a[i] = a[j];
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
void MakeMinHeap(int a[], int n) {
for (int i = n / 2 - 1; i >= 0; i--)
MinHeapFixdown(a, i, n);
}
void MinheapsortTodescendarray(int a[], int n)
{
for (int i = n - 1; i >= 1; i--)
{
Swap(a[i], a[0]);
MinHeapFixdown(a, 0, i);
}
}
递归实现代码:
两个子序列归并操作:
void MergeArray(int *list, int first, int mid, int last, int *temp) {
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (list[i] <= list[j])
temp[k++] = list[i++];
else
temp[k++] = list[j++];
}
while (i <= m)
temp[k++] = list[i++];
while (j <= n)
temp[k++] = list[j++];
for (i = 0; i < k; i++)
list[first + i] = temp[i];
}
递归调用:
void MergeSort(int *list, int first, int last, int *temp) {
if (first < last)
{
int mid = (first + last) / 2;
MergeSort(list, first, mid, temp);
MergeSort(list, mid + 1, last, temp);
MergeArray(list, first, mid, last, temp);
}
else
temp[first] = list[first];
}
非递归实现归并排序: * 递归过程是将待排序集合一分为二,直至排序集合就剩下一个元素位置,然后不断的合并两个排好序的数组。 * 非递归思想为,将数组中的相邻元素两两配对。用merge函数将他们排序,构成n/2组长度为2的排序好的子数组段, 然后再将他们排序成长度为4的子数组段,如此继续下去,直至整个数组排好序。
具体代码实现:
void MergeSort2(int *list, int first, int last, int *temp, int len) {
int s = 2;
int i;
while (s <= len) {
i = 0;
while (i + s <= len) {
MergeArray (list, i, i+s/2-1, i+s-1, temp);
i += s;
}
MergeArray (list, i, i+s/2-1, len-1, temp);
s *= 2;
}
MergeArray (list, 0, s/2-1, len-1, temp);
}
具体代码实现:
归并过程:
int AdjustArray(int *list, int l, int r) {
int i = l, j = r;
int x = list[l];
while (i < j) {
while(i < j && list[j] >= x)
j--;
if(i < j) {
list[i] = list[j];
i++;
}
while(i < j && list[i] < x)
i++;
if(i < j) {
list[j] = list[i];
j--;
}
}
list[i] = x;
return i;
}
递归过程:
void QuickSort(int *list, int l, int r) {
if (l < r) {
int i = AdjustArray(list, l, r);
QuickSort(list, l, i - 1);
QuickSort(list, i + 1, r);
}
}
本文参考了 结构之法 算法之道 以及 More Windows Blog 的几篇文章,在此表示感谢。