您的位置:首页 > 理论基础 > 数据结构算法

数据结构 排序算法

2013-09-16 23:43 197 查看
//============================================================================
// Name        : shuanfa.cpp
// Author      : yuanxiang
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <windows.h>
#include <sys/timeb.h>
#include <time.h>
using namespace std;

struct timeval
{
long tv_sec;
long tv_usec;
};

int gettimeofday(struct timeval* tv)
{
    union{
             long long ns100;
             FILETIME ft;
    }now;
    GetSystemTimeAsFileTime (&now.ft);
    tv->tv_usec = (long) ((now.ns100 ) % 1000000LL);
    tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL);
    return (0);
}

//获取1970年至今UTC的微妙数
time_t GetUtcCaressing()
{
    timeval tv;
    gettimeofday(&tv);
    return ((time_t)tv.tv_sec*(time_t)1000000+tv.tv_usec);
}

void print(int src[],int length){
	for(int i=0;i<length;i++){
		cout<<src[i]<<" ";
	}
	cout<<endl;
}

void swap(int& a,int& b){
	int temp = a;
	a = b;
	b=temp;
}

//冒泡排序
void maopoSort(int src[],int length){
  cout<<"冒泡排序:";
  print(src,length);
  for(int i=0;i<length;i++){
      for(int j=0;j<length-1-i;j++){
        if(src[j]>src[j+1]){
        	int temp = src[j];
        	src[j] = src[j+1];
        	src[j+1]=temp;
        }
      }
  }
  print(src,length);
}
//简单选择排序
void xuanzheSort(int src[],int length){
	  cout<<"简单排序:";
	  print(src,length);
	  for(int i=0;i<length;i++){
		  int k = i;
	      for(int j=i+1;j<length;j++){
	        if(src[j]<src[k]){
	             k = j;
	        }
	      }
	      if(k!=i){
	    	  swap(src[k],src[i]);
	      }
	  }
	  print(src,length);
}

//插入排序
void charuSort(int src[],int length){
	  cout<<"插入排序排序:";
	  print(src,length);
   for(int i=0;i<length;i++){
	   int j=0;
	   int k=src[i];
	   for(j=i-1;j>=0&&src[j]>k;j--){
		   src[j+1]=src[j];
	   }
	   if(j+1!=i)
	      src[j+1] = k ;
   }
   print(src,length);
}

//快速排序
void kuaisuSort(int src[],int begin,int end){
   if(begin>=end)
		return;
   int mid =begin;
   int i=begin+1;
   int j=end;
   while(i<=j){
      while(src[i]<=src[mid]&&i<end) i++;
      while(src[j]>=src[mid]&&j>begin) j--;
      if(i<j){
        swap(src[i],src[j]);
      }else{
    	  break;
      }
      i++;
      j--;
   }
   swap(src[mid],src[j]);
   kuaisuSort(src,begin,j-1);
   kuaisuSort(src,j+1,end);
}
void kuaisuSort(int src[],int length){
	cout<<"快速排序:";
	print(src,length);
	kuaisuSort(src,0,length-1);
	print(src,length);
}

//堆排序
void maxHeap(int src[],int k,int length){//从0开始
   int m = src[k];
   int i = k;
   while(i<length){
	   int left=2*(i+1)-1;
	   int right=2*(i+1);
	   int lagest = 0;

	   if(right<length)
	       lagest = src[right]>src[left]?right:left;
	   else if(left<length)
		   lagest = left;
	   else
		   break;

	   if(src[lagest]>m){
              src[i]=src[lagest];
              i = lagest;
	   }else{
		   break;
	   }
   }
   if(i!=k)
	   src[i] = m;
}

void CreateDui(int src[],int length){
   for(int i=length/2-1;i>=0;i--){
	   maxHeap(src,i,length);
	   //print(src,length);
   }
}

void duiSort(int src[],int length){
	cout<<"堆排序:";
	print(src,length);
	CreateDui(src,length);
	for(int i=length-1;i>=1;i--){
	     swap(src[0],src[i]);
	     maxHeap(src,0,i);
	}
	print(src,length);
}

//希尔排序
void shellSortDela(int src[],int dela,int begin,int length){
    for(int i=begin;i<length;i+=dela){
    	int j=i-dela;
    	int m = src[i];
	   for(j=i-dela;src[j]>m&&j>=begin;){
           src[j+dela] = src[j];
           j=j-dela;
	   }
	   src[j+dela] = m;
    }
   // print(src,length);
}

void shellSort(int src[],int length){
	cout<<"shell排序:";
	print(src,length);
	for(int dela=length/2;dela>0;dela/=2){
		for(int i=0;i<dela;i++)
           shellSortDela(src,dela,i,length);
	}
	print(src,length);
}

//归并排序
void merge(int a[],int low,int mid,int high){
     int* b=new int[high-low+1];
     int i=low;
     int j=mid+1;
     int k=0;
     while(i<=mid&&j<=high){
    	 b[k++]=a[i]<=a[j]?a[i++]:a[j++];
     }
     while(i<=mid)
    	 b[k++]=a[i++];
     while(j<=high)
    	 b[k++]=a[j++];
    // memcpy(&a[low],b,(high-low+1)*sizeof(int));
     for(i=low;i<=high;i++){
          a[i] = b[i-low];
      }
     delete b;
}

void mergeSort(int a[],int begin,int end){
       if(begin>=end)
    	   return;
       int mid=(begin+end)/2;
       mergeSort(a,begin,mid);
       mergeSort(a,mid+1,end);
       merge(a,begin,mid,end);

}
void mergeSort(int a[],int length){
	cout<<"归并排序:";
	print(a,length);
	mergeSort(a,0,length-1);
	print(a,length);
}

//基数排序
void jisuSort(int a[],int length){
	cout<<"基数排序:";
	print(a,length);
   int* b = new int[10*length];
   int k[10]={0};
   bool flag=true;
   int m=1;
   while(flag){
	   flag = false;
	   memset(k,0,10*sizeof(int));
	   for(int i=0;i<length;i++){
		   int t = abs(a[i])/m;
		   if(t/10>0)
				 flag=true;
		   *(b+length*(t%10)+*(k+t%10)) = a[i];
		   *(k+t%10) = *(k+t%10)+1;
	   }
	   m *= 10;
	   int n=0;
	   for(int i=0;i<10;i++){
		   if(k[i]!=0){
               for(int j=0;j<k[i];j++){
            	   a[n++]=*(b+length*i+j);
               }
		   }
	   }
   }
   print(a,length);
   memset(k,0,10*sizeof(int));
   for(int i=0;i<length;i++){
      if(a[i]<0){
    	 *(b+k[0]) = a[i];
    	 k[0]++;
      }else{
     	 *(b+length+k[1]) = a[i];
     	 k[1]++;
      }
   }
   int n=0;
   for(int j=k[0]-1;j>=0;j--){
	   a[n++]=*(b+j);
   }
   for(int j=0;j<k[1];j++){
	   a[n++]=*(b+length+j);
   }
   delete b;
   print(a,length);
}
//计算排序时间
void computeTime(int a[],int length,void(*func)(int a[],int length)){
	int* b=new int[length];
	for(int i=0;i<length;i++){
		b[i]=a[i];
	}
	time_t t1= GetUtcCaressing();
	func(b,length);
	time_t t2= GetUtcCaressing();
	cout<<"算法消耗时间(100NS):"<<t2<<"-"<<t1<<"="<<t2-t1<<endl;
	delete b;
}

int main() {
	int a[]={3,2,-1,6,4,12,0,7,-4,29,-20};
	int length = sizeof(a)/sizeof(int);
	computeTime(a,length,maopoSort);
	computeTime(a,length,xuanzheSort);
	computeTime(a,length,charuSort);
	computeTime(a,length,kuaisuSort);
	computeTime(a,length,duiSort);
	computeTime(a,length,shellSort);
	computeTime(a,length,mergeSort);
	computeTime(a,length,jisuSort);

	return 0;
}


运行结果:

冒泡排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476843755--1476843755=0

简单排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476843755--1476843755=0

插入排序排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476843755--1476843755=0

快速排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476843755--1476843755=0

堆排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476843755--1476843755=0

shell排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476833754--1476843755=10001

归并排序:3 2 -1 6 4 12 0 7 -4 29 -20

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476833754--1476833754=0

基数排序:3 2 -1 6 4 12 0 7 -4 29 -20

0 -1 2 3 4 -4 6 7 12 -20 29

-20 -4 -1 0 2 3 4 6 7 12 29

算法消耗时间(100NS):-1476833754--1476833754=0


Shell排序

#include<iostream>

using namespace std;

void ShellPass(int R[],int d){

int j;

int temp;

for(int i=d;i<=9;i++)

if(R[i]<R[i-d]){

temp=R[i];j=i-d;

do{ //实现内部小循环R[0],R[3],R[6],R[9],do-while

R[j+d]=R[j];

j=j-d;

}while (j>0&&temp<R[j]);

R[j+d]=temp;

}

}

void ShellSort(int R[]){

int increment=10;

do{

increment=(increment+1)/2;

ShellPass(R,increment);

}while(increment>1);

}
int main(){
int R[10]={9,8,6,5,4,7,3,2,1,0};

//int R[10]={49,38,65,97,76,13,27,49,55,4};

ShellSort(R);

for(int i=0;i<10;i++)

printf("%5d",R[i]);

return 0;

}


快速排序:

以首元素为基准,先从右边向左边扫描,再从左边向右边扫描。将叫小的数移动到前面,较大的数移动到后面,则第一轮过后,

首元素将所有数据分成了左右两部分,让后对左右两部分继续进行相同的操作。

1、

#include<stdio.h>

#include<stdlib.h>

#include<iostream>

using namespace std;

void quicksort(int data[], int low, int high)

{

int i, pivot, j;

if(low < high){

pivot = data[low];

i = low;

j = high;

while(i < j){

//cout<<"data[j]: "<<data[j]<<endl;

while(i < j && data[j] >= pivot){

j--;

}

if(i < j){

data[i++] = data[j];

}

while(i < j && data[i] <= pivot){

i++;

}

if(i < j){

data[j--] = data[i]; //每次的赋值都是填充上一次的基准所在位置元素

}

}

data[i] = pivot; //将基准赋给

quicksort(data, low, i - 1);

quicksort(data, i + 1, high);

}

}

int main(void)

{

int i;

int arr[8];

printf("Input six number: \n");

for(i = 0; i < 8; i++){

scanf("%d", &arr[i]);

}

quicksort(arr, 0, 7);

for(i = 0; i < 8; i++){

printf("%d ", arr[i]);

}

}

2、

//注意if(low<high)这一判断语句,否则不知道终止条件

#include<iostream>

using namespace std;

int partion(int data[],int low ,int high){

int i,j,k;

i=low;j=high;k=data[i];

while(i<j){

while((i<j)&&data[j]>=k){

j--;

}

data[i++]=data[j];

while((i<j)&&data[i]<=k){

i++;

}

data[j--]=data[i];



}

data[i]=k;

return i;

}

void qsort(int data[],int low,int high){



int temp;

if(low<high){ //注意这个地方大判断语句特别重要,一定要加

temp=partion(data,low,high);

qsort(data,low,temp-1);

qsort(data,temp+1,high);

}

}

int main()

{

int a[5];

int i;

for(i=0;i<5;i++){

scanf("%d",&a[i]);

}

qsort(a,0,4);

for(i=0;i<5;i++){

printf("%d ",a[i]);

}

printf("\n");

}

堆排序:

//首先建立大根堆,结点从0开始到n-1,建堆的时候从n/2-1到0,不断的筛选

//新的结点交换有可能破换原有的秩序。

//建立好大根堆之后呢,从n-1到0遍历结点,不断的将最后一个结点(依次递减)元素和

//首结点元素交换,保证最后一个结点(依次递减)始终最大,与此同时,首结点再交换之后

//秩序发生了变换,因此重新构建大根堆.....

#include<stdio.h>

void heap_adajust(int array[],int i,int length){

int j=2*i+1;

int temp=array[i];

while(j<=length-1){

if((array[j]<array[j+1])&&j<length-1){ //保证j对应的结点总是最大

j=j+1;

}

if(array[i]<array[j]){ //让当前结点与最大结点交换

array[i]=array[j];

array[j]=temp;

i=j;

j=2*i+1;

}

//i=j;

else{

break;

}

}

//array[i]=temp;

}

void heap_sort(int array[],int length){

int temp;

int i;

for(i=(length/2)-1;i>=0;--i)

heap_adajust(array,i,length); //不断的筛选,大者上浮,小者筛选下去,要判断交换后的结点是否破换原有的秩序

//for(i=length-1;i>=0;--i){

for(i=length-1;i>=0;--i){

temp=array[0];

array[0]=array[i];

array[i]=temp;

heap_adajust(array,0,i);

}

}

void main()

{

int i;

//int array[10]={0,1,2,3,4,5,6,7,8,9};

int array[10]={9,8,7,6,5,4,3,2,1,0};

heap_sort(array,10);

for(i=0;i<=9;++i){

printf("%d\n",array[i]);

}

}

参考:

http://book.51cto.com/art/201108/287061.htm

http://baike.baidu.com/view/157305.htm

/article/1389267.html

书籍:数据结构(严蔚敏)

二分查找:

一、递归写法

#include<stdio.h>

//设数组是由小到大的顺序排序的

int search_loc(int a[],int k,int low,int high){

int mid;

if(k>a[high]||k<a[low]) //判断是否在数组内

return -1;

if(low>high)

return -1;

mid=(low+high)/2;

if(a[mid]==k)

return mid;

if(a[mid]<k){

return search_loc(a,k,mid+1,high);

}

if(a[mid]>k){

return search_loc(a,k,low,mid-1);

}

return -1;



}

void main()

{

int loc;

int k;

int a[7]={1,2,3,4,5,6,7};

int len=7;

int low=0;

int high=len-1;

printf("请输入需要查找的数:\n");

scanf("%d",&k);

loc=search_loc(a,k,0,6);

printf("%d\n",loc);

}

二、非递归写法

//注意考虑到边界情况,找到则返回在数组中的序号(从0开始),否则返回-1

#include<stdio.h>

int bi_search(int a[],int len,int k){

int low=0;

int high=len-1;

int mid=(low+high)/2;

if(a==NULL||len==0||k<a[low]||k>a[high])

return -1;

while(low<=high){ //考虑边界

if(a[mid]==k)

return mid;

if(a[mid]>k){

high=mid-1;

mid=(low+high)/2;

}

if(a[mid]<k){

low=mid+1;

mid=(low+high)/2;

}

}

return -1;

}

void main(){

int loc;

int a[7]={1,2,3,5,6,7,8};

int k;

scanf("%d",&k);

loc=bi_search(a,7,k);

printf("%d\n",loc);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: