排序演算法集:冒泡、插入、希爾、快速(陣列實現、連結串列實現)

gudesheng發表於2008-01-03

// Sort.cpp : Defines the entry point for the console application.
/*
 作者:成曉旭
 時間:2001年6月29日(09:09:38-10:30:00)
 內容:完成選擇排序演算法函式,氣泡排序演算法<第一版>
 時間:2001年10月4日(21:00:38-21:30:00)
 內容:完成選擇排序演算法函式,氣泡排序演算法,插入排序演算法(陣列實現)<第二版>
 時間:2001年10月5日(12:00:38-13:00:00)
 內容:完成希爾排序演算法(陣列實現),選擇排序演算法函式,氣泡排序演算法,插入排序演算法(連結串列實現)<第二版>
 時間:2001年10月6日(13:00:38-14:00:00)
 內容:完成快速排序演算法函式,氣泡排序演算法,插入排序演算法(連結串列實現)<第二版>
*/

#include "stdafx.h"
#include "stdlib.h"
#define  SIZE 10

int TestArray0[SIZE] = {9,7,5,3,1,8,6,4,2,0};
//int TestArray1[SIZE] = {0,2,4,6,8,10,12,14,16,18};
//int TestArray2[SIZE] = {1,3,5,7,9,11,13,15,17,19};
int TestArray3[SIZE] = {11,3,25,67,89,110,513,595,107,19};
//int TestArray3[SIZE] = {5,7,1,2};
struct Node
{
 int data;
 struct Node *link;
};

void Swap(int *p1,int *p2)
{
 int t;
 t   = *p1;
 *p1 = *p2;
 *p2 = t;
}
//==============================應用程式<第一版>==============================
/*
 選擇排序演算法函式Select_Sort_Array<用陣列實現>
 引數描述:
 int array[] :被排序的陣列
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Select_Sort_Array(int array[],int n,int increase)
{
 int i,j,k;
 for(i=0;i {
  for(k=i,j=i+1;j  {
   if (increase)
   {
    if(array[k]>array[j]) k=j;
   }
   else
   {
    if(array[k]   }
  }
  if(k!=i) Swap(&array[k],&array[i]);
 }
}
/*
 選擇排序演算法函式Select_Sort_Pointer<用指標實現>
 引數描述:
 int *start :被排序的陣列地址(0號元素地址)
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Select_Sort_Pointer(int *start,int n,int increase)
{
 int
  *p1,//外迴圈指標,指向[0-n-1]個元素
  *p2,//內迴圈指標,指向[p1的下一個-n]個元素
     *pt;//臨時指標變數
 for(p1=start;p1 {
  for(pt=p1,p2=p1+1;p2  {
   if(increase)
   {
    if(*pt>*p2) pt=p2;
   }
   else
   {
    if(*pt<*p2) pt=p2;
   }
  }
  if(pt!=p1) Swap(pt,p1);
 }
}
/*
 插入排序演算法函式Insert_Sort_Array<用陣列實現>
 引數描述:
 int array[] :被排序的陣列
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Insert_Sort_Array(int array[],int n,int increase)
{
 int i,j,t;
 for(i=1;i {
  if(increase)
  {
   for(t=array[i],j=i-1;j>=0 && t < array[j];j--)
    array[j+1] = array[j];
  }
  else
  {
   for(t=array[i],j=i-1;j>=0 && t > array[j];j--)
    array[j+1] = array[j];
  }
  array[j+1] = t;
  printf("第%d輪外迴圈:/tj = %d/tArray[j+1] = %d/n",i,j,array[j+1]);
 }
}
/*
 插入排序演算法函式Insert_Sort_Pointer<用指標實現>
 引數描述:
 int *start :被排序的陣列地址(0號元素地址)
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Insert_Sort_Pointer(int *start,int n,int increase)/*<函式有錯誤!!!>*/
{
 int
  *p1,//外迴圈指標,指向[0-n-1]個元素
  *p2,//內迴圈指標,指向[p1的下一個-n]個元素
     *pt;//臨時指標變數
 for(p1=start+1;p1 {
  if(increase)
  {
   for(pt=p1,p2=p1-1;p2>=start && *pt < *p2;p2--)
    *(p2+1) = *p2;
  }
  else
  {
   for(pt=p1,p2=p1-1;p2>=start && *pt > *p2;p2--)
    *(p2+1) = *p2;
  }
  *(p2++) = *pt;
 }
}
/*
 氣泡排序演算法函式Ebullient_Sort_Array<用陣列實現>
 引數描述:
 int array[] :被排序的陣列
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Ebullient_Sort_Array(int array[],int n,int increase)
{

 int i,j;
 for(i=0;i {
  for(j=i+1;j  {
   if(increase)
   {
    if(array[i]>array[j]) Swap(&array[i],&array[j]);
   }
   else
   {
    if(array[i]   }
  }
 }
}

/*
 氣泡排序演算法函式Ebullient_Sort_Pointer<用指標實現>
 引數描述:
 int *start :被排序的陣列地址(0號元素地址)
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Ebullient_Sort_Pointer(int *start,int n,int increase)
{
 int *p1,//外迴圈指標,指向[0-n-1]個元素
  *p2;//內迴圈指標,指向[p1的下一個-n]個元素
 for(p1=start;p1  for(p2=p1+1;p2  {
   if(increase)
   {
    if(*p1>*p2)  Swap(p1,p2);
   }
   else
   {
    if(*p1<*p2)  Swap(p1,p2);
   }
  }
}

void PrintArrayValue(int *startarray,int n)
{
 int *p;
 int i;
 for(p=startarray,i=0;p  printf("Array[%d] = %d/t",i,*p);
}
//==============================應用程式<第一版>==============================

//==============================應用程式<第二版>==============================
//------------------------------陣列實現部分----------------------------------
/*
 希爾(Shell)排序演算法函式Shell_Sort_Array<用陣列實現>
 引數描述:
 int array[] :被排序的陣列
 int n  :被排序的陣列元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Shell_Sort_Array(int array[],int n,int increase)
{
 int i,j, //迴圈控制變數
  step, //每輪內迴圈插入的步長
  t;  //內迴圈臨時變數
 for(step = n / 2;step > 0;step = step / 2)
  for(i = step;i < n;i++)
  {
   /*讓出當前考察元素的儲存位置*/
   t = array[i];
   for(j = i - step;j >= 0 && t < array[j]; j = j - step)
    array[j+step] = array[j];  /*移動元素*/
   /*插入當前考察的元素*/
   array[j+step] = t;
   printf("第%d輪外迴圈:/tj = %d/tArray[j+step] = %d/n",step,j,array[j+step]);
  }
}
/*
 快速排序演算法函式Quick_Sort_Array0<用陣列實現>
 (快速排序演算法是對冒泡演算法的改進演算法)(遞迴演算法)
 引數描述:
 int array[] :被排序的陣列
 int low  :被排序的陣列的上界
 int high :被排序的陣列的下界
*/
void Quick_Sort_Array0(int array[],int low,int high)
{
 int i,j,t;
 if(low {
  i = low;
  j = high;
  t = array[low];
  while(i  {
   while(i t)
    j--;
   if(i    array[i++] = array[j];
   while(i    i++;
   if(i    array[j--] = array[i];
  }
  array[i] = t;
  /*遞迴,劃分左子序列*/
  Quick_Sort_Array0(array,low,i-1);
  /*遞迴,劃分右子序列*/
  Quick_Sort_Array0(array,i+1,high);
 }
}
/*
 快速排序演算法函式Quick_Sort_Array1<用陣列實現>
 (快速排序演算法是對冒泡演算法的改進演算法)(非遞迴演算法)
 引數描述:
 int array[] :被排序的陣列
 int n  :被排序的陣列的元素個數
 int increase:排序升降標誌 
  increase = 1 <按升序排序>
  increase = 0 <按降序排序>
*/
void Quick_Sort_Array1(int array[],int n)
{
 int i,j,t,  //迴圈控制器及臨時變數
  low,high, //排序子序列的上,下界
  top;  //堆疊陣列棧頂指標
 int stack[SIZE][2];  //程式堆疊
 stack[0][0] = 0;
 stack[0][1] = n-1;
 top = 1;
 while(top>0)
 {
  top--;
  low = i = stack[top][0];
  high = j = stack[top][1];
  t = array[low];
  /*對自low至high的陣列元素以array[low]為基準進行劃分*/
  while(i  {
   while(it)
    j--;
   if(i    array[i++] = array[j];
   while(i    i++;
   if(i    array[j--] = array[i];
  }
  array[i] = t;
  /*左邊子序列起止位置進棧*/
  if(i-1>low)
  {
   stack[top][0] = low;
   stack[top][1] = i-1;
   top++;
  }
  /*右邊子序列起止位置進棧*/
  if(high>i+1)
  {
   stack[top][0] = i+1;
   stack[top][1] = high;
   top++;
  }
 }
}
//------------------------------陣列實現部分----------------------------------
//------------------------------連結串列實現部分----------------------------------
/*
Node *CreateSortNode()功能:建立排序的單連結串列,並返回一個指向其頭節點的指標
 引數描述:
  int nodecount:新建連結串列的節點個數
 返回值描述:
  CreateSortNode: 新建連結串列的頭指標
*/
Node *CreateSortNode(int nodecount,int *array)
{
 Node
  *p1,//指向產生的新節點
  *p2,//指向連結串列的尾節點
  *head;//指向連結串列的頭節點
 int i;
 head = NULL;
 for(i=0;i {
  p1=(Node *)malloc(sizeof(Node));
  p1->data = array[i];
  p1->link = NULL;
  if (i == 0)
   head = p1;
  else
   p2->link = p1;
  p2 = p1;
 }
 p2->link = NULL;
 return(head);
}
/*
void ListSortNOde()功能:遍歷排序的單連結串列的所有節點
 引數描述:
  link_table *start:連結串列的頭指標
*/
void ListSortNode(Node *start)
{
 Node *p;
 int i = 0;
 p = start;
 printf("The Link Table Data........./n");
 if (p->link !=NULL)
 {
  do
  {
   printf("Data[%d].data = %d/n",i++,p->data);
   p = p->link;
  }while(p!= NULL);
 }
}
/*
Node *Select_Sort_LinkTable()功能:單連結串列的選擇法排序,並返回被排序後連結串列的首指標
 引數描述:
  Node *head: 單連結串列的首指標
  int increase: 排序升降標誌 
   increase = 1 <按升序排序>
   increase = 0 <按降序排序>
 返回值描述:
  Select_Sort_LinkTable: 被排序後連結串列的首指標
*/
Node *Select_Sort_LinkTable(Node *head,int increase)
{
 Node *newhead, //排序後新連結串列的頭節點指標
   *tail,  //排序後新連結串列的尾節點指標
   *p,  //連結串列遍歷指標
   *pre,  //最小節點的前驅節點指標
   *min;  //本輪的最小節點
 /*設定排序新連結串列的首指標為空*/
 newhead = NULL;
 /*在剩餘的連結串列中查詢鏈值最小的節點*/
 while(head!=NULL)
 {
  for(p = min = head;p->link != NULL;p = p->link)
  {
   if(increase)
   {
    if(p->link->data < min->data)
    {
     /*儲存更小節點的前驅節點指標*/
     pre = p;
     /*儲存更小節點指標*/
     min = p->link;
    }
   }
   else
   {
    if(p->link->data > min->data)
    {
     pre = p;
     min = p->link;
    }
   }
  }
  /*讓查詢到的最小節點從原連結串列中脫掉*/
  if(min == head)
   /*最小節點是首節點*/
   head = head->link;
  else
   pre->link = min->link;
  /*將依次找到的最小節點掛到排序連結串列中*/
  if(newhead == NULL)
   /*首次找到的最小節點*/
   tail = newhead = min;
  else
   tail = tail->link = min;
 }
 /*在排序連結串列中加上鍊表結束符*/
 if(newhead != NULL)
  tail->link = NULL;
 return(newhead);
}
/*
Node *Insert_Sort_LinkTable()功能:單連結串列的插入法排序,並返回被排序後連結串列的首指標
 引數描述:
  Node *head: 單連結串列的首指標
  int increase: 排序升降標誌 
   increase = 1 <按升序排序>
   increase = 0 <按降序排序>
 返回值描述:
  Select_Sort_LinkTable: 被排序後連結串列的首指標
*/
Node *Insert_Sort_LinkTable(Node *head,int increase)//<函式有錯誤!!!>2002/09/08修改正確
{
 Node *s,  //還未排序節點序列的首結點指標
   *p,  //連結串列遍歷指標
   *pre,  //當前節點的前驅節點指標
   *min;  //本輪的最小節點
 s = head->link;
 head->link = NULL;
 while(s != NULL)
 {
  for(min = s,p = head;p != NULL && p->data < min->data;pre = p,p = p->link);
  s = s->link;
  if(p == head)
   head = min;
  else
   pre->link = min;
  min->link = p;
 }
 return(head);
}
/*
Node *Ebullient_Sort_LinkTable()功能:單連結串列的冒泡法排序,並返回被排序後連結串列的首指標
 引數描述:
  Node *head: 單連結串列的首指標
  int increase: 排序升降標誌 
   increase = 1 <按升序排序>
   increase = 0 <按降序排序>
 返回值描述:
  Ebullient_Sort_LinkTable: 被排序後連結串列的首指標
*/
Node *Ebullient_Sort_LinkTable(Node *head,int increase)
{
 Node *q,  //氣泡排序的附加輔助節點(總是指向要交換的兩個節點的前一個節點)
   *tail,  //排序後新連結串列的尾節點指標
   *p,  //連結串列遍歷指標
   *t;  //交換節點時的臨時變數  
 q = (Node *)malloc(sizeof(Node));
 q->link = head;
 head = q;
 for(tail = NULL;tail != head;tail = p)
  for(p = q = head;q->link->link != tail;q = q->link)
  {
   if(q->link->data > q->link->link->data)
   {
    /*交換兩個元素*/
    /*t指標指向要交換的後一個節點*/
    t = q->link->link;
    q->link->link = t->link;
    t->link = q->link;
    q->link = t;
    /*p指向本輪冒泡的元素*/
    p = q->link->link;
   }
  }
 q = head;
 head = head->link;
 free(q);
 return(head);
}
//------------------------------連結串列實現部分----------------------------------
//==============================應用程式<第二版>==============================
/*
 主程式開始部分
*/
int main(int argc, char* argv[])
{
 Node *head,*s_head;
 /*
 printf("原始陣列元素........./n");
 PrintArrayValue(TestArray0,SIZE);
 Insert_Sort_Array(TestArray0,SIZE,1);
 //Shell_Sort_Array(TestArray0,SIZE,1);
 //Quick_Sort_Array1(TestArray0,SIZE);
 //Quick_Sort_Array0(TestArray0,0,SIZE-1);
 printf("排序後陣列元素........./n");
 PrintArrayValue(TestArray0,SIZE);
 /**/
 /**/
 printf("[原始]陣列元素........./n");
 head = CreateSortNode(SIZE,TestArray3);
 ListSortNode(head);
 printf("[選擇排序]後陣列元素........./n");
 s_head = Insert_Sort_LinkTable(head,1);
 //s_head = Ebullient_Sort_LinkTable(head,1);
 ListSortNode(s_head);
 /**/
 return 0;
}

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=935636


相關文章