排序总结

本文详细介绍了五种经典的排序算法,包括插入排序、希尔排序、冒泡排序、快速排序和选择排序,每种算法都提供了详细的实现代码及基本思想。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)插入排序

//基本思想:每一趟将一个待排序的记录,按其关键字值的大小插入到已经排序的部分文件中适当位置上,
//直到全部插入完成


#include <stdio.h>
#include <stdlib.h>

void InsertSort(int r[],int n)
{
   for(int i=0;i<n-1;i++)
   {
       for(int j=i+1;j>0;j--)
       {
            if(r[j]<r[j-1])
           {
               int tmp = r[j];
               r[j] = r[j-1];
               r[j-1] = tmp;
           }
      }
  }
}

int main()
{
     int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
     InsertSort(ary,12);
     for(int i=0;i<12;i++)
    {
         printf("%d ",ary[i]);
    }
     printf("/n");

     return 0;
}

 

 

2)希尔排序

基本思想:把记录按下标的一定增量分组,对每组记录使用插入排序,随着增量逐渐减小,所分成的组包含的记录越来越多,到增量的值减少到1时,整个数据合成为一组,构成一组有序记录,则完成排序。

 

#include "stdafx.h"


void shellsort(int r[],int n)
{
  int i,j,gap,x;
 gap = n/2;
 while(gap>0)
 {
  for(i=gap;i<n;i++)
  {
   j=i-gap;
   while(j>=0)
   {
    if(r[j] > r[j+gap])
    {
     x=r[j];
     r[j]=r[j+gap];
     r[j+gap]=x;
    }
    j=j-gap;
   }
   
  }
  gap=gap/2;
 }
}


int _tmain(int argc, _TCHAR* argv[])
{
 int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
 shellsort(ary,12);
 for(int i=0;i<12;i++)
 {
  printf("%d ",ary[i]);
 }
 printf("/n");
 return 0;
}

 

3)冒泡排序

//冒泡排序的基本思想:通过无序区中相邻记录关键字间的比较和位置交换,是关键字最小的记录如气泡一般逐渐
//往上“漂浮”直至“水面”。整个算法是从最下面的记录开始,对每两个相邻的关键字进行比较,且使关键字较小
//的记录换至关键字较大的记录之上,使得经过一趟冒泡排序后,关键字最小的记录到达最上端,接着,再在剩下的
//记录中找关键字最小的记录,并把它换至第二个位置上。依此类推,直到所有记录都有序为止。

#include <stdio.h>
#include <stdlib.h>

void BubbleSort(int r[],int n)
{
 for(int i=0;i<n;i++)
 {
  for(int j=n-1;j>i;j--)
  {
   if(r[j]<r[j-1])
   {
    int tmp = r[j];
    r[j] = r[j-1];
    r[j-1] = tmp;    
   }
  }
 }
}

int main()
{
 int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
 BubbleSort(ary,12);
 for(int i=0;i<12;i++)
 {
  printf("%d ",ary[i]);
 }
 printf("/n");

 return 0;
}

 

4)快速排序

//快速排序基本思想:在待排序的n个记录中任取一个记录(通常取第一个记录),把该记录放入最终位置后,数据序列被此记录分割成
//两部分。所有关键字比该记录小的放置在前一部分,所有比它大的放置在后一部分,并把该记录排在这两部分的中间,这个过程称作
//一趟快速排序。之后对所有的两部分分别重复上述过程,直至每部分内只有一个记录为止。简而言之,每趟使表的第一个元素入终位,
//将表一分为二,对子表按递归方式继续这种划分,直至划分的子表长为1。
#include <stdio.h>

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

void QuickSort(int r[],int start,int end)
{
 int i=start,j=end;
 if(start<end)     //递归条件(集合元素数目必须大于1)
 {
  while(1)                // 找到一个元素,把数组分开成左边小,右边大的数组,用中间元素分开
  {
   while((r[i] < r[j])&& i<j) j--;    //从右端找比item小的元素,交换 (item为待定放中间的目标元素,初始为第一个元素)
   if(i==j) break;
   swap(r[i],r[j]);
   i++;

   while((r[j] > r[i])&& i< j) i++;  //从左端找比item大的元素,交换
   if(i==j)
    break;
   swap(r[i],r[j]);
   j--;
   
  }

  
  //一下用于调试的打印 begin ***
  //打印左边部分(小于分界点的所有元素)
  for(int k=start;k<i;k++)
  {
   printf("%d ",r[k]);
  }
  printf(" <---left:%d:right--> ",r[i]);  //分界点元素
  //打印右边部分(大于分界点的所有元素)
  for(int k=i+1;k<=end;k++)
  {
   printf("%d ",r[k]);
  }
  printf("/n");
  //end ***
  
  QuickSort(r,start,i-1);
  QuickSort(r,i+1,end);
 }
}

int main()
{
 int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
 //int ary[12]={1,2,3,4,5,6,7,8,9,10,11,12};   //顺序
 //int ary[12]={12,11,10,9,8,7,6,5,4,3,2,1};   //逆序
 QuickSort(ary,0,11);
 for(int i=0;i<12;i++)
 {
  printf("%d ",ary[i]);
 }
 printf("/n");

 return 0;
}

 

5)选择排序

//选择排序基本思想:每一趟排序在n-i+1(i=1,2,3,...n-1)个记录中选取关键字最小的记录,并和第i个记录交换之。

#include <stdio.h>

void SelectSort(int r[],int n)
{
 for(int i=0;i<n;i++)
 {
  int pos=i;
  // 选择比如r[i]最小的元素,与r[i]交换位置
  for(int j=i+1;j<n;j++)
  {
   if(r[pos]>r[j])
   {
    pos = j;          // 记比r[i]小的元素下标号
   }
  }
  //交换
  int tmp = r[i];
  r[i] = r[pos];
  r[pos] = tmp;
 }
}

int main()
{
 int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
 //int ary[12]={1,2,3,4,5,6,7,8,9,10,11,12};   //顺序
 //int ary[12]={12,11,10,9,8,7,6,5,4,3,2,1};   //逆序
 SelectSort(ary,12);
 for(int i=0;i<12;i++)
 {
  printf("%d ",ary[i]);
 }
 printf("/n");

 return 0;
}

 

6)  堆排序

堆排序是在排序过程中,将向量中存储的数据看成是一颗完全二叉树,利用完全二叉树中双亲节点和孩子节点之间的内在关系来选择关键字最小的记录。

 

//最大堆操作类

//maxheap.h

//堆是一种完全二叉树(可以用数组来表示)
#ifndef _MAP_HEAP_H_
#define _MAP_HEAP_H_

#include <string.h>

template<class T>
class CMaxHeap
{
public:
 CMaxHeap():m_iSize(0),m_pData(NULL),m_iMaxSize(0){};
 CMaxHeap<T>(int size)
 {
  m_pData = new T[size];
  m_iSize = 0;
  m_iMaxSize = size;
 }
 //template <typename U> CMaxHeap(U* pAry,int size)
 //{
 // m_pData = new U[size];
 // Initialize(pAry,size);
 //}
 CMaxHeap(T* pAry,int size)
 {
  m_pData = new T[size];
  m_iMaxSize = size;
  Initialize(pAry,size);
 }

 //公用方法
 void Initialize(T* pAry,int size);
 int DelMax(T &max);
 int Insert(T elem);
private:
 int m_iSize;
 int m_iMaxSize;
 T *m_pData;

};
#if 0
template <class T> void CMaxHeap<T>::Initialize(T* pAry,int size)
{
 //m_pData = new T[size];
 m_iSize = size;
 int i=size/2;             //从第一个具有孩子节点的节点开始,往上找
 while(i>0)
 {
  //寻找合适的插入位置
  int cl=2*i;   //i的子节点
  int cr=2*i+1;
  while(cl>1 && cl<=size)
  {
   if(pAry[cl/2-1]<pAry[cl-1])
   {
    T tmp;
    tmp = pAry[cl/2-1];
    pAry[cl/2-1] = pAry[cl-1];
    pAry[cl-1] = tmp;
   }
   cl/=2;
  }
  while(cr>1 && cr<=size)
  {
   if(pAry[cr/2-1]<pAry[cr-1])
   {
    T tmp;
    tmp = pAry[cr/2-1];
    pAry[cr/2-1] = pAry[cr-1];
    pAry[cr-1] = tmp;
   }
   cr/=2;
  }
  printf("i=%d/n",i);
  for(int j=0;j<12;j++)
  {
   printf("%d ",pAry[j]);
  }
  printf("/n"); 
  
  i--;
 }
 memcpy(m_pData,pAry,size*sizeof(T));
 
}
#else
template <class T> void CMaxHeap<T>::Initialize(T* pAry,int size)
{
 //m_pData = new T[size];
 memcpy(m_pData,pAry,size*sizeof(T));
 m_iSize = size;
 int i=size/2;             //从第一个具有孩子节点的节点开始,往上找
 while(i>0)
 {
  //寻找合适的插入位置
  int c=2*i;   //i的子节点

  while(c>1 && c<=size)
  {
   if(c+1<=size && m_pData[c-1] < m_pData[c])
   {
    c++;
   }
   if(m_pData[c/2-1]<m_pData[c-1])
   {
    T tmp;
    tmp = m_pData[c/2-1];
    m_pData[c/2-1] = m_pData[c-1];
    m_pData[c-1] = tmp;
   }

   c/=2;
  }

  i--;
 }
 
}
#endif


template <class T> int CMaxHeap<T>::DelMax(T &max)
{
 if(m_iSize > 0)    //不能删除空堆
 {
  max = m_pData[0];
  
  T tmp = m_pData[m_iSize-1];
  m_pData[0] = tmp;
  //自顶向下交换
  int i=1;            
  while(i<=m_iSize)
  {
   int c=2*i;   //i的子节点

   if(c+1<=m_iSize && m_pData[c-1]<m_pData[c+1-1])    //如果有rightchild且left<right
   {
    c++;
   }
   if(c>m_iSize)
    break;
   if(m_pData[i-1]<m_pData[c-1])
   {
    T tmp;
    tmp = m_pData[i-1];
    m_pData[i-1] = m_pData[c-1];
    m_pData[c-1] = tmp;
   }
   i=c;
  }
  m_iSize--;
  return 0;
  
 }
 return -1;
}
//最大堆的插入操作,自底向上的交换
template <class T> int CMaxHeap<T>::Insert(T elem)
{
 if(m_iSize >= m_iMaxSize)
 {
  //TRACE("NO Memory");
  return -1;
 }

 int i=m_iSize+1;            
 while(i> 1)   //向上最多搜索到根
 {
  int c=i/2;   //i的父亲节点

  if(m_pData[c-1]<m_pData[i])
  {
   T tmp;
   tmp = m_pData[c-1];
   m_pData[c-1] = m_pData[i-1];
   m_pData[i-1] = tmp;
  }
  else
  {
   break;
  }
  i=c;
 }
 m_pData[i-1]=elem;
 m_iSize++;
 //for debug
 printf("m_iSize=%d/n",m_iSize);
 for(int j=0;j<m_iSize;j++)
 {
  printf("%d ",m_pData[j]);
 }
 printf("/n");

 return 0;
}

 

//heapsort.cpp

#include <stdio.h>
#include "MaxHeap.h"

int main()
{

 int ary[12]={49,38,65,97,76,13,27,49,55,4,24,56};
 CMaxHeap<int> maxheap(ary,12);
 
 for(int i=0;i<12;i++)
 {
  int elem;
  maxheap.DelMax(elem);
  printf("%d ",elem);
 }
 printf("/n");

 //Insert node into maxheap
 //CMaxHeap<int> maxheap1(100);
// for(int i=0;i<12;i++)
 //{
 // maxheap1.Insert(ary[i]);
// }
 //printf("/n"); 
 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值