插入排序與歸併排序及優化
阿新 • • 發佈:2019-01-08
看CLRS順便做下筆記總結一下,理清思路。(所有排序例子皆為從小到大,各位覺得哪裡能更好地改進都可以指出來)
插入排序(c語言實現)
最壞情況下的執行時間是Θ(n*n),跟氣泡排序,選擇排序的最壞情況下的執行時間是相同的
但是,運算的速度 插入>選擇(相比冒泡交換的次數較少)>冒泡
最簡單的例子啦,打牌的時候一張一張的拿到手裡插入排序。
上程式碼
#include<stdio.h>
#include<stdlib.h>
int main(void){
int j,i,num,key;
scanf("%d",&num);
int *ptr;
ptr=(int *)malloc(num*sizeof(int));//動態記憶體分配
for(i=0;i<num;i++){
scanf("%d",&ptr[i]);
}
for(i=1;i<num;i++){
key=ptr[i];//你拿到的“牌”
j=i-1;//通過迭代找到合適的位置,將其他牌向前推
while(j>=0&&ptr[j]>key){
ptr[j+1]=ptr[j];
j-=1;
}
ptr[j+1 ]=key;//最後把牌放進去
}
for(i=0;i<num;i++){
printf("%d ",ptr[i]);
}
free(ptr);
return 0;
}
以上的方法是從迭代實現插入排序
那麼我們試下遞迴實現插入排序
#include<stdio.h>
#include<stdlib.h>
void insert_sort(int *ptr,int num);
int main(void){
int i,num,*ptr;
scanf("%d",&num);
ptr=(int *)malloc(num*sizeof(int));
for(i=0;i<num;i++){
scanf("%d",&ptr[i]);
}
insert_sort(ptr,num-1);
for(i=0;i<num;i++){
printf("%d ",ptr[i]);
}
free(ptr);
return 0;
}
void insert_sort(int *ptr,int num){
int j,i,key;
static index=0;
j=index+1;
key=ptr[j];
i=j-1;
while(i>=0&&ptr[i]>key){
ptr[i+1]=ptr[i];
i--;
}
ptr[i+1]=key;
index++;
if(index<num){
insert_sort(ptr,num);
}
}
歸併排序(c語言實現)
採用的是分治的思想Divide and Conquer
最壞情況下的執行時間是Θ(n*Ign),其中Ign相比任何的線性函式增長慢,所以歸併排序的效能要優於插入排序。
歸併排序就等於畫樹,其中樹的每一層加起來都等於cn,樹的高度一共是Ign層,merge的子程式耗費的時間是Θ(n)
一共加起來的時間就是cn*lgn+Θ(n),通過漸近符號得到最高項就是Θ(n*Ign)
上程式碼(這裡的歸併排序並沒有採用哨兵的方法)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void merge_sort(int *ptr,int low,int high);
void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh);
int main(void){
int size,index;
scanf("%d",&size);
int *ptr;
ptr=(int *)malloc(size*sizeof(int));
for(index=0;index<size;index++){
scanf("%d",&ptr[index]);
}
merge_sort(ptr,0,size-1);
for(index=0;index<size;index++){
printf("%d ",ptr[index]);
}
free(ptr);
return 0;
}
void merge_sort(int *ptr,int low,int high){
if(low<high){
int middle;
middle=low+(high-low)/2;
merge_sort(ptr,low,middle);
merge_sort(ptr,middle+1,high);
merge(ptr,low,middle,middle+1,high);
}
}
void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh){
int num;
num=(lefthigh-leftlow+1)+(righthigh-rightlow+1);
int *sort_array;
int index=0;
int leftindex=leftlow;
int rightindex=rightlow;
sort_array=(int *)malloc(num*sizeof(int));
while(leftindex<=lefthigh&&rightindex<=righthigh){
if(ptr[leftindex]<=ptr[rightindex]){
sort_array[index++]=ptr[leftindex++];
}
else{
sort_array[index++]=ptr[rightindex++];
}
}
while(leftindex<=lefthigh){
sort_array[index++]=ptr[leftindex++];
}
while(rightindex<=righthigh){
sort_array[index++]=ptr[rightindex++];
}
memcpy(ptr+leftlow,sort_array,num*sizeof(int));
free(sort_array);
}
那麼,就如函式y=n*n與函式y’=n*n*n一樣存在一個點,使得小於該點時y
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30
void merge_sort(int *,int ,int );
void merge(int *,int ,int ,int ,int );
void insert_sort(int *,int ,int );
int main(void){
int i,size,*ptr;
scanf("%d",&size);
ptr=(int *)malloc(size*sizeof(int));
for(i=0;i<size;i++){
scanf("%d",&ptr[i]);
}
merge_sort(ptr,0,size-1);
for(i=0;i<size;i++){
printf("%d ",ptr[i]);
}
free(ptr);
return 0;
}
void merge_sort(int *ptr,int low,int high){
if((high-low)<=MAX){
insert_sort(ptr,low,high);
}
else if((high-low)>MAX){
int mid;
mid=low+(high-low)/2;
merge_sort(ptr,low,mid);
merge_sort(ptr,mid+1,high);
merge(ptr,low,mid,mid+1,high);
}
}
void insert_sort(int *ptr,int low,int high){
int i,j;
int key;
for(j=low+1;j<=high;j++){
key=ptr[j];
i=j-1;
while(i>=low&&ptr[i]>key){
ptr[i+1]=ptr[i];
i--;
}
ptr[i+1]=key;
}
}
void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh){
int size;
size=(lefthigh-leftlow)+1+(righthigh-rightlow)+1;
int *sort_array;
sort_array=(int *)malloc(size*sizeof(int));
int index=0;
int leftindex=leftlow;
int rightindex=rightlow;
while(leftindex<=lefthigh&&rightindex<=righthigh){
if(ptr[leftindex]<ptr[rightindex]){
sort_array[index++]=ptr[leftindex++];
}
else{
sort_array[index++]=ptr[rightindex++];
}
}
while(leftindex<=lefthigh){
sort_array[index++]=ptr[leftindex++];
}
while(rightindex<=righthigh){
sort_array[index++]=ptr[rightindex++];
}
memcpy(ptr+leftlow,sort_array,size*sizeof(int));
free(sort_array);
}