排序算法集:冒泡、插入、希尔、快速(数组实现、链表实现)

来源:互联网 发布:淘宝上靠谱的鞋店 编辑:程序博客网 时间:2024/05/17 04:05

// 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


原创粉丝点击