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

转载 2012年03月26日 11:52:23

// 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<n-1;i++)
 {
  for(k=i,j=i+1;j<n;j++)
  {
   if (increase)
   {
    if(array[k]>array[j]) k=j;
   }
   else
   {
    if(array[k]<array[j]) k=j;
   }
  }
  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<start+n-1;p1++)
 {
  for(pt=p1,p2=p1+1;p2<start+n;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<n;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<start+n;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<n-1;i++)
 {
  for(j=i+1;j<n;j++)
  {
   if(increase)
   {
    if(array[i]>array[j]) Swap(&array[i],&array[j]);
   }
   else
   {
    if(array[i]<array[j]) Swap(&array[i],&array[j]);
   }
  }
 }
}

/*
 冒泡排序算法函数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<start+n-1;p1++)
  for(p2=p1+1;p2<start+n;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<startarray+n;p++,i++)
  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<high)
 {
  i = low;
  j = high;
  t = array[low];
  while(i<j)
  {
   while(i<j && array[j] > t)
    j--;
   if(i<j)
    array[i++] = array[j];
   while(i<j && array[i] <= t)
    i++;
   if(i<j)
    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<j)
  {
   while(i<j && array[j]>t)
    j--;
   if(i<j)
    array[i++] = array[j];
   while(i<j && array[i]<=t)
    i++;
   if(i<j)
    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<nodecount;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;
}

 

js实现排序算法(冒泡、选择、插入、二分插入、快速、希尔)

插入排序从第一个元素开始,该元素可以认为已经被排序; 取出下一个元素,在已经排序的元素序列中从后向前扫描; 如果该元素(已排序)大于新元素,将该元素移到下一位置; 重复步...

js实现排序算法(冒泡、选择、插入、二分插入、快速、希尔)

插入排序插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表 排序过程大概如下: 从第一个元素开始,该元素可以认为已经被排序; 取出下一个元素,...

七大排序算法(冒泡,选择,插入,二分法排序,希尔,快速,合并,堆排序)的java实现(14/8/3更新加入二分排序)

冒泡排序 思路:就是每次将最大或最小的元素放到数组的最后,so easy!时间复杂度为(O(n^2)) public class BubbleSort { public static void bu...

八大经典排序算法基本思想及代码实现(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,基数排序)

一.插入排序——简单插入排序基本思想:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。def insertSort(arr): if len(...

几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)

最近决定每天学点数据结构与算法,写博客来督促自己继续学习~ 以下的每个排序的写法格式基本按照先介绍基本思想,再描述具体过程,最后是具体代码。关于复杂度等问题后续更新。如有写的不严谨的地方,欢迎指出,...

各种排序算法实现——基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序

各种排序算法总结见http://blog.csdn.net/huahuahailang/article/details/8716434   一、基数排序 #include #include ...

几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)

最近决定每天学点数据结构与算法,写博客来督促自己继续学习~ 以下的每个排序的写法格式基本按照先介绍基本思想,再描述具体过程,最后是具体代码。关于复杂度等问题后续更新。如有写的不严谨的地方,欢迎指...

C语言8种排序算法及其实现 1.希尔排序 2.二分插入法 3.直接插入法 4.带哨兵的直接排序法 5.冒泡排序 6.选择排序 7.快速排序 8.堆排序

一.希尔(Shell)排序法(又称宿小增量排序,是1959年由D.L.Shell提出来的) /* Shell 排序法 */ #include void sort(int v[],int n) { ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:排序算法集:冒泡、插入、希尔、快速(数组实现、链表实现)
举报原因:
原因补充:

(最多只允许输入30个字)