码迷,mamicode.com
首页 > 编程语言 > 详细

数据结构复习之内部排序算法总结

时间:2015-07-26 11:05:56      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

1.三种选择排序(简单选择排序,树形选择排序,堆排序)

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdlib> 
#include<cstdio>
const int INF=0X3f3f3f3f;
using namespace std;

typedef struct
{
   int a[100];
   int len;
   void outList(){
           for(int i=1; i<=len; ++i)
               cout<<a[i]<<" ";
           cout<<endl;
   }
}list;
list L;


int smaller(int a, int b)
{
   return a>b?b:a;
}
/**********************************************************************************/
void sample_selection_sort()//简单选择排序 
{
    int i, j, k;
    for(i=1; i<=L.len; i++)
     {
         k=i;
         for(j=i+1; j<=L.len; j++)
           if(L.a[k]>L.a[j])
             k=j;
        if(k!=i)
          {
              L.a[i]^=L.a[k];
              L.a[k]^=L.a[i];
              L.a[i]^=L.a[k];
          }
     }
} 
/**********************************************************************************/
int tree[400];
void tree_choose_sort(int ld, int rd, int p)//树形选择排序,和线段树差不多 
{
   if(rd==ld)
     tree[p]=L.a[ld];
   else
     {
         int mid=(ld+rd)/2;
        tree_choose_sort(ld, mid, p<<1);
        tree_choose_sort(mid+1, rd, p<<1|1);
        tree[p]=smaller(tree[p<<1], tree[p<<1|1]);
     }
}

void update_tree(int ld, int rd, int p, int key)//树形选择排序
{
    if(rd==ld)
     {
       if(key==tree[p])
          tree[p]=INF;
     } 
    else
     {
         int mid=(ld+rd)/2;
         if(key==tree[p<<1]) 
            update_tree(ld, mid, p<<1, key);
         else
            update_tree(mid+1, rd, p<<1|1, key);
         tree[p]=smaller(tree[p<<1], tree[p<<1|1]);
     }
}
/**********************************************************************************/

typedef struct tree//树形选择排序 
{
   int d;
   struct tree *lchild;
   struct tree *rchild;
}*TREE;
void build_tree(TREE &T, int ld, int rd)//树形选择排序
{
   if(ld==rd)
    { 
       T->lchild=T->rchild=NULL;
       T->d=L.a[ld];
    }
   else
   {
          int mid=(rd+ld)/2;
          T=(TREE)malloc(sizeof(tree));
          T->lchild=(TREE)malloc(sizeof(tree));
          T->rchild=(TREE)malloc(sizeof(tree));
       build_tree(T->lchild, ld, mid);
       build_tree(T->rchild, mid+1, rd);
       T->d=smaller(T->lchild->d, T->rchild->d);
   }
}

void Update_tree(TREE &T, int key)//树形选择排序
{
   if(T)
   {
      if(!T->lchild && !T->rchild)
        {
            if(T->d==key)
              T->d=INF;
        }
      else
       {
             if(key==T->lchild->d)
               Update_tree(T->lchild, key);
             else if(key==T->rchild->d)
               Update_tree(T->rchild, key);
             T->d=smaller(T->lchild->d, T->rchild->d);
       }
   }
}
/**********************************************************************************/

void heapAdjust(int ld, int rd){//堆排序, 排序区间[ld,rd] 
    int rc = L.a[ld];
    int cur = ld;
    for(int p = ld*2; p<=rd; p=p*2){
        if(p<rd && L.a[p] > L.a[p+1]) ++p;//取左右子树的最小值
        if(rc < L.a[p]) break;//如果父节点的值比左右子树的值都小,那么已经调整好了,已经是小堆顶了
        L.a[cur] = L.a[p];//否则交换父节点和左右子树最小的子树的值,父节点的值存在rc中,所以只要将最小子树的值赋给父节点就好 
        cur = p;
    }
    L.a[cur] = rc;
}

/**********************************************************************************/

int main() {
    int i;
   scanf("%d", &L.len);
   for(i=1; i<=L.len; i++)
     scanf("%d", &L.a[i]);
   //selection_sort();//选择排序 
   
//   tree_choose_sort(1, L.len, 1);//树形选择排序 
//   
//   int n=L.len;
//   while(n--)
//    {
//       printf("%d ", tree[1]);
//       update_tree(1, L.len, 1, tree[1]);
//    }
   
//   TREE T;//树形选择排序 
//   build_tree(T, 1, L.len);
//   int n=L.len;
//   while(n--)
//    {
//       printf("%d ", T->d);
//       Update_tree(T, T->d);
//    }


    for(int i=L.len/2; i>=1; --i)//将整个区间调整成小堆顶 
        heapAdjust(i, L.len);
    
    for(int i=1; i<=L.len; ++i) {
        cout<<L.a[1]<<" "; 
        L.a[1] = L.a[L.len-i+1];//将最后一个元素赋给第一个元素 
        heapAdjust(1, L.len-i);//重新调整堆 
    }
    cout<<endl;
    return 0;
}

 2.冒泡排序

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdlib> 
#include<cstdio>
const int INF=0X3f3f3f3f;
using namespace std;

typedef struct
{
   int a[100];
   int len;
   void outList(){
           for(int i=1; i<=len; ++i)
               cout<<a[i]<<" ";
           cout<<endl;
   }
}list;
list L;

void bubble_sort()
{
   int i, j, change=1;
   for(j=L.len; change && j>=1; j--)
     {
         change=0;
         for(i=1; i<j; i++)
           if(L.a[i]>L.a[i+1])
             {
                L.a[i]^=L.a[i+1];
               L.a[i+1]^=L.a[i];
                 L.a[i]^=L.a[i+1];
                 change=1;
             }
     }
}

int main() {
    int i;
   scanf("%d", &L.len);
   for(i=1; i<=L.len; i++)
     scanf("%d", &L.a[i]);
    bubble_sort(); 
    return 0;
}

3.快速排序

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdlib> 
#include<cstdio>
const int INF=0X3f3f3f3f;
using namespace std;

typedef struct
{
   int a[100];
   int len;
   void outList(){
           for(int i=1; i<=len; ++i)
               cout<<a[i]<<" ";
           cout<<endl;
   }
}list;
list L;

int partition(int low, int high)//将数据元素划分为左边都小于枢轴,右边元素都大于枢轴 
{
   //采用三者取中的方法选择枢轴 
   if((L.a[high]-L.a[low]) * (L.a[high]-L.a[(low+high)/2]) < 0)
            swap(L.a[low], L.a[high]);
   else if((L.a[(low+high)/2]-L.a[low]) *(L.a[(low+high)/2]-L.a[high]) < 0)
           swap(L.a[low], L.a[(low+high)/2]);
   int pivotkey=L.a[low];// 枢轴关键字
   while(low<high)
     {
         while(low<high && L.a[high]>=pivotkey)
           high--;
         L.a[low]=L.a[high];
         while(low<high && L.a[low]<=pivotkey)
           low++;
         L.a[high]=L.a[low];
     }
   L.a[low]=pivotkey; 
   return low;
} 

void Qsort(int low, int high)//快速排序 
{
   if(low<high)
    {
       int p=partition(low, high);
       Qsort(low, p-1);
       Qsort(p+1, high);
    }
}


int main() {
   int i;
   scanf("%d", &L.len);
   for(i=1; i<=L.len; i++)
     scanf("%d", &L.a[i]);
    Qsort(1, L.len); 
    L.outList();
    return 0;
}

 

4.归并排序

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<cstdlib> 
#include<cstdio>
const int INF=0X3f3f3f3f;
using namespace std;

typedef struct
{
   int a[100];
   int len;
   void outList(){
           for(int i=1; i<=len; ++i)
               cout<<a[i]<<" ";
           cout<<endl;
   }
}list;
list L;

void Merge(int lr, int rr)//归并排序 
{
   int atemp[100], mid=(lr+rr)/2;//atemp[]存放两个有序表合并后的结果
   int i, j, k;
   for(i=lr, j=mid+1, k=0; i<=mid && j<=rr; )//将两个有序表的合并代码 
     {
         if(L.a[i]<=L.a[j])
           atemp[k++]=L.a[i++];
         else
          atemp[k++]=L.a[j++];     
     }
   if(i>mid)
     for(k; j<=rr; j++)
       atemp[k++]=L.a[j];
   if(j>rr)
     for(k; i<=mid; i++)
       atemp[k++]=L.a[i]; 
   memcpy(L.a+lr, atemp, sizeof(int)*k);//将两段儿有序表合并后的结果 
}                                     //复制到原来对应的位置上 

void Msort(int ld, int rd)
{
   if(ld<rd)
     {
         int mid=(ld+rd)/2;
         Msort(ld, mid);
         Msort(mid+1, rd);
         Merge(ld, rd);//回溯法合并有序 序列 
     }
}


int main() {
   int i;
   scanf("%d", &L.len);
   for(i=1; i<=L.len; i++)
     scanf("%d", &L.a[i]);
    Msort(1, L.len); 
    L.outList();
    return 0;
}

5.插入排序

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio> 
using namespace std;
const int INF=0X3f3f3f3f;
typedef struct
{
   int a[100];
   int len;
   void outList(){
        for(int i=1; i<=len; ++i){
            cout<<a[i]<<" ";
        }
        cout<<endl;
   }
}list;
list L;

/*********************************************************************/ 
void direct_insertion_sort()//直接插入排序 
{
   int i, j;
   for(i=2; i<=L.len; i++)
     {
         L.a[0]=L.a[i];
         for(j=i-1; L.a[0]<L.a[j]; j--)
           L.a[j+1]=L.a[j];
         L.a[j+1]=L.a[0];
     }
}

/*********************************************************************/ 

void benary_insertion_sort1()//折半插入排序 
{
   int i, j, left, right, mid;
   for(i=2; i<=L.len; i++)
     {
        left=1;
        right=i-1;
        L.a[0]=L.a[i];
        while(left<=right)
         {
               mid=(left+right)/2;
               if(L.a[mid]<=L.a[0])
                  left=mid+1;
               else
                  right=mid-1;
         }
        for(j=i-1; j>=left; j--)
          L.a[j+1]=L.a[j];
        L.a[j+1]=L.a[0];
     }
} 

/*********************************************************************/ 

void benary_insertion_sort2(){//折半插入排序 
    for(int i=2; i<=L.len; ++i){
        L.a[0] = L.a[i];
        int k = upper_bound(L.a+1, L.a+i, L.a[0]) - L.a;//返回最后一个大于key的位置 
        for(int j=i; j>k; --j)
            L.a[j] = L.a[j-1];
        L.a[k] = L.a[0];
    }
}

/*********************************************************************/ 
void twoWay_insertion_sort()//二路插入排序 
{
   int *d=(int *)malloc(sizeof(int)*L.len);
   int first, final, i, j;
   first=final=0;
   d[0]=L.a[1];
   for(i=2; i<=L.len; i++)
     {
         if(L.a[i]>=d[final])//直接添加在尾部 
           d[++final]=L.a[i];
         else if(L.a[i]<=d[first])//直接添加在头部 
           d[first=(first-1+L.len)%L.len]=L.a[i];
         else//在头部和尾部中间
          {
               for(j=final++; d[j]>=L.a[i]; j=(j-1+L.len)%L.len)
                 d[(j+1)%L.len]=d[j];
               d[(j+1)%L.len]=L.a[i];
          }
     }
    for(i=first, j=1; i!=final; i=(i+1)%L.len, j++)
      L.a[j]=d[i];
}

/*********************************************************************/ 
void shell_insertion_sort(int d)
{
   int i, j;
   for(i=d+1; i<=L.len; i++)
     {
         if(L.a[i]<L.a[i-d])//需要将L.a[i]插入有序增量字表 
           {
                 L.a[0]=L.a[i];
               for(j=i-d; j>=1 && L.a[0]<=L.a[j]; j-=d)
                  L.a[j+d]=L.a[j];
               L.a[j+d]=L.a[0];
           }
     }
}

void shellsort()//希尔排序 
{
    int dk[]={5, 3, 1};//设置子序列的增量 
    for(int i=0; i<3; i++)
      shell_insertion_sort(dk[i]);
}

/*********************************************************************/ 

typedef struct xxx{
    int head;//头结点 
    int a[100];
    int next[100];//记录下一个元素的位置 
    int len;
    xxx(){
        head = 1;
        memset(next, 0, sizeof(next));
    }
    void outList(){
        for(int i=1; i<=len; ++i){
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
}Listx; 

Listx Lx;

void table_insertion_sort(){//表插入排序,相当于静态链表 
    for(int i=2; i<=Lx.len; ++i){
        int pre, p;
        for(p=Lx.head; p && Lx.a[p]<Lx.a[i]; pre=p, p=Lx.next[p]);
        if(p==0){
            Lx.next[pre] = i;
        } else if(p==Lx.head){
            Lx.next[i] = Lx.head;
            Lx.head = i;
        } else {
            Lx.next[pre] = i;
            Lx.next[i] = p;
        } 
    }
    //输出
    for(int i=Lx.head; i; i = Lx.next[i]) 
        cout<<Lx.a[i]<<" ";
    cout<<endl;
}

void arrang_table() {
    int p = Lx.head, q;
    for(int i=1; i<Lx.len; ++i){
        while(p < i) p = Lx.next[p];//第i个记录在表中的位置不应该小于 i,如果小于i,说明该元素已经被交换位置了,可以通过next继续寻找 
        q = Lx.next[p];//指向下一个节点 
        if(p!=i){//第p个元素应该在第i个位置 
            swap(Lx.a[i], Lx.a[p]);
            swap(Lx.next[i], Lx.next[p]);
            Lx.next[i] = p;//该元素之前的位置 p,指向被移走的记录,使得以后可由while循环找回 
        }
        p = q;
    }
    
    for(int i=1; i<=Lx.len; ++i) 
        cout<<Lx.a[i]<<" ";
    cout<<endl;
}

/*********************************************************************/ 

int main()
{
    int i;
    scanf("%d", &Lx.len);
    for(i=1; i<=Lx.len; i++)
        scanf("%d", &Lx.a[i]);
//    benary_insertion_sort2();
//    L.outList();
    table_insertion_sort();
    arrang_table();
    return 0;
}

/*
8
49 38 6 5 97 76 13 27 49
*/

 

数据结构复习之内部排序算法总结

标签:

原文地址:http://www.cnblogs.com/hujunzheng/p/4676810.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!