引言
所用教材为《算法导论》第三版,下面是前三章中一些算法的代码实现。
插入排序
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#include <stdio.h>
void InsertionSort(int* ary, int len){
for(int j=1; j<len; j++){
int key = ary[j];
int i = j - 1;
while(i>=0 && ary[i]>key){
ary[i+1] = ary[i];
i = i - 1;
}
ary[i+1] = key;
}
}
int main(){
int ary[] = {4,5,2,4,7,13,42,6,42,34,1,3};
int len = GET_ARRAY_LEN(ary);
InsertionSort(ary, len);
for(int i=0; i<len; i++){
printf("%d ", ary[i]);
}
}
冒泡排序
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#include <stdio.h>
void BubbleSort(int* ary, int len){
for(int j=1; j<len; j++){
for(int i=j; i>=0; i--){
if(ary[i-1] > ary[i]){
int tem = ary[i-1];
ary[i-1] = ary[i];
ary[i] = tem;
}
}
}
}
int main(){
int ary[] = {4,5,2,4,7,13,42,6,42,34,1,3};
int len = GET_ARRAY_LEN(ary);
BubbleSort(ary, len);
for(int i=0; i<len; i++){
printf("%d ", ary[i]);
}
}
这个程序有bug,在g++下没问题,在Clang++下就会出现问题,详见关于算法笔记(1)中冒泡排序的bug
归并排序
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#include <stdio.h>
#include <math.h>
void Merge(int* ary, int r, int mid, int p){
int len1 = mid - p + 1;
int len2 = r - mid;
int* temAry1 = new int[len1];
int* temAry2 = new int[len2];
for(int i=0; i<len1; i++)
temAry1[i] = ary[p+i-1];
for(int i=0; i<len2; i++)
temAry2[i] = ary[mid+i];
int i = 0;
int j = 0;
int k = p-1;
while(i < len1 && j < len2){
if(temAry1[i] <= temAry2[j]){
ary[k] = temAry1[i];
i = i + 1;
}
else{
ary[k] = temAry2[j];
j = j + 1;
}
k = k + 1;
}
while(i < len1){
ary[k] = temAry1[i];
i = i + 1;
k = k + 1;
}
while(j < len2){
ary[k] = temAry2[j];
j = j + 1;
k = k + 1;
}
}
void MergeSort(int* ary, int r, int p=1){
if(p<r){
int mid = floor((r + p) / 2);
MergeSort(ary, mid, p);
MergeSort(ary, r, mid+1);
Merge(ary, r, mid, p);
}
}
int main(){
int ary[] = {4,5,2,4,7,13,42,6,42,34,1,3};
int len = GET_ARRAY_LEN(ary);
MergeSort(ary, len);
for(int i=0; i<len; i++){
printf("%d ", ary[i]);
}
}
逆序对个数
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#include <stdio.h>
#include <math.h>
int Merge(int* ary, int r, int mid, int p){
int len1 = mid - p + 1;
int len2 = r - mid;
int* temAry1 = new int[len1];
int* temAry2 = new int[len2];
for(int i=0; i<len1; i++)
temAry1[i] = ary[p+i-1];
for(int i=0; i<len2; i++)
temAry2[i] = ary[mid+i];
int i = 0;
int j = 0;
int k = p-1;
int count = 0;
while(i < len1 && j < len2){
if(temAry1[i] <= temAry2[j]){
ary[k] = temAry1[i];
i = i + 1;
}
else{
ary[k] = temAry2[j];
j = j + 1;
count += (len1 - i);
}
k = k + 1;
}
while(i < len1){
ary[k] = temAry1[i];
i = i + 1;
k = k + 1;
}
while(j < len2){
ary[k] = temAry2[j];
j = j + 1;
k = k + 1;
}
return count;
}
int CountInversion(int* ary, int r, int p=1){
if(p<r){
int mid = floor((r + p) / 2);
int c = 0;
c += CountInversion(ary, mid, p);
c += CountInversion(ary, r, mid+1);
c += Merge(ary, r, mid, p);
return c;
}else
return 0;
}
int main(){
int ary[] = {4,5,2,4,7,13,42,6,42,34,1,3};
int len = GET_ARRAY_LEN(ary);
printf("Inversion Number: %d", CountInversion(ary, len));
}