找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3328|回复: 4

排序大全

[复制链接]
发表于 2014-7-28 16:22:32 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
经过几天的努力,终于自己吧所有重要排序算法都学了一遍且都实现了一遍,以图形化来展示排序过程也是一种乐趣。
我这个程序的特点是
        相似算法排在一列。比如冒泡的几个改进算法都在前面有+号,有几个+号就代表改进几次
        显示步数,步数在一定程度上决定了算法复杂度,我在每一层循环中都会递增步数
        可以设置显示方块大小,排序数量n取决于这个变量,可以设置排序速度,可以暂停、继续和重来
        所有递归排序均采用非递归形式,所有排序方式如果存在参数则取最优值,例如希尔排序的间隔数组,所有排序算法均在已知数组大小和最大值的情况下进行优化

效果图:

QQ图片20140728162008.jpg
QQ图片20140728162043.jpg
QQ图片20140728162135.jpg


下面是MFC核心代码,12种排序算法,洋洋洒洒也有1000行了:

       
  1. // drawsortDlg.cpp : implementation file
  2. //

  3. #include "stdafx.h"
  4. #include "drawsort.h"
  5. #include "drawsortDlg.h"

  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <stack>
  9. using namespace std;

  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif


  15. #include <vector>
  16. #include <time.h>
  17. using namespace std;
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CDrawsortDlg dialog

  20. CString SORTNAME[TYPE_MAX]={"冒泡排序","冒泡排序改进","双向冒泡排序","快速排序","插入排序",
  21.                 "二分插入排序","希尔排序","选择排序","锦标赛排序","堆排序","归并排序","基数排序","",""};


  22. CDrawsortDlg::CDrawsortDlg(CWnd* pParent /*=NULL*/)
  23.         : CDialog(CDrawsortDlg::IDD, pParent)
  24. {
  25.         //{{AFX_DATA_INIT(CDrawsortDlg)
  26.         //}}AFX_DATA_INIT
  27.         // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  28.         m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  29. }

  30. void CDrawsortDlg::DoDataExchange(CDataExchange* pDX)
  31. {
  32.         CDialog::DoDataExchange(pDX);
  33.         //{{AFX_DATA_MAP(CDrawsortDlg)
  34.         DDX_Control(pDX, IDC_BLOCKSIZE, m_blocksize);
  35.         DDX_Control(pDX, IDC_VELOCITY, m_velocity);
  36.         DDX_Control(pDX, IDC_TYPELIST, m_typelist);
  37.         DDX_Control(pDX, IDC_DRAW, m_draw);
  38.         //}}AFX_DATA_MAP
  39. }

  40. BEGIN_MESSAGE_MAP(CDrawsortDlg, CDialog)
  41.         //{{AFX_MSG_MAP(CDrawsortDlg)
  42.         ON_WM_PAINT()
  43.         ON_WM_QUERYDRAGICON()
  44.         ON_BN_CLICKED(IDDRAW, OnDraw)
  45.         ON_WM_TIMER()
  46.         ON_NOTIFY(NM_CUSTOMDRAW, IDC_VELOCITY, OnCustomdrawVelocity)
  47.         ON_BN_CLICKED(IDGOON, OnGoon)
  48.         ON_BN_CLICKED(IDPAUSE, OnPause)
  49.         //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()

  51. /////////////////////////////////////////////////////////////////////////////
  52. // CDrawsortDlg message handlers

  53. BOOL CDrawsortDlg::OnInitDialog()
  54. {
  55.         CDialog::OnInitDialog();

  56.         srand(time(NULL));
  57.         // Set the icon for this dialog.  The framework does this automatically
  58.         //  when the application's main window is not a dialog
  59.         SetIcon(m_hIcon, TRUE);                        // Set big icon
  60.         SetIcon(m_hIcon, FALSE);                // Set small icon
  61.        
  62.         // TODO: Add extra initialization here
  63.         m_typelist.InsertString(0,"左半:");
  64.         m_typelist.InsertString(1,"冒泡排序");
  65.         m_typelist.InsertString(2,"+冒泡排序改进(哨兵)");
  66.         m_typelist.InsertString(3,"++冒泡排序改进(双向)");
  67.         m_typelist.InsertString(4,"+++快速排序");
  68.         m_typelist.InsertString(5,"插入排序");
  69.         m_typelist.InsertString(6,"+二分插入排序");
  70.         m_typelist.InsertString(7,"++希尔排序(最优系数)");
  71.         m_typelist.InsertString(8,"");
  72.         m_typelist.InsertString(9,"右半");
  73.         m_typelist.InsertString(10,"选择排序");
  74.         m_typelist.InsertString(11,"+锦标赛排序(树形排序)");
  75.         m_typelist.InsertString(12,"++堆排序");
  76.         m_typelist.InsertString(13,"归并排序");
  77.         m_typelist.InsertString(14,"基数排序(桶排序)");

  78.         m_typelist.SetCurSel(0);

  79.         for(int i=0;i<TYPE_MAX;i++)
  80.         {
  81.                 toDrawQueue.push_back(queue<DrawData>());
  82.         }

  83.         SetTimer(1,200,NULL);
  84.         srand(time(NULL));
  85.         m_velocity.SetRange(10,1000);       
  86.         m_velocity.SetPos(200);

  87.         m_blocksize.SetRange(2,20);
  88.         m_blocksize.SetPos(10);

  89.         running=true;

  90.         return TRUE;  // return TRUE  unless you set the focus to a control
  91. }

  92. // If you add a minimize button to your dialog, you will need the code below
  93. //  to draw the icon.  For MFC applications using the document/view model,
  94. //  this is automatically done for you by the framework.

  95. void CDrawsortDlg::OnPaint()
  96. {
  97.         if (IsIconic())
  98.         {
  99.                 CPaintDC dc(this); // device context for painting

  100.                 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  101.                 // Center icon in client rectangle
  102.                 int cxIcon = GetSystemMetrics(SM_CXICON);
  103.                 int cyIcon = GetSystemMetrics(SM_CYICON);
  104.                 CRect rect;
  105.                 GetClientRect(&rect);
  106.                 int x = (rect.Width() - cxIcon + 1) / 2;
  107.                 int y = (rect.Height() - cyIcon + 1) / 2;

  108.                 // Draw the icon
  109.                 dc.DrawIcon(x, y, m_hIcon);
  110.         }
  111.         else
  112.         {
  113.                 CDialog::OnPaint();

  114.                 int queuenum=toDrawQueue.size();

  115.                 RECT drawrt;
  116.                 m_draw.GetClientRect(&drawrt);
  117.                 CClientDC dc(&m_draw);
  118.                 CDC MemDC;
  119.                 CBitmap MemBitmap;
  120.                 MemDC.CreateCompatibleDC(&dc);
  121.                 MemBitmap.CreateCompatibleBitmap(&dc,drawrt.right,drawrt.bottom);
  122.                 MemDC.SelectObject(&MemBitmap);
  123.                 int BARSIZE=m_blocksize.GetPos();
  124.                
  125.                 CBrush clearbrush(RGB(255,255,255));
  126.                 MemDC.FillRect(&drawrt,&clearbrush);
  127.                 CBrush normalbrush(RGB(0,0,255)),stressbrush(RGB(255,0,0));
  128. //                CPen normalpen(PS_SOLID,1,RGB(0,0,255)),stresspen(PS_SOLID,1,RGB(255,0,0));
  129.                 int blockheight=drawrt.bottom*2/queuenum;

  130.                 for(int i=0;i < queuenum;i++)
  131.                 {
  132.                         if(toDrawQueue.at(i).empty())
  133.                                 continue;
  134.                         queue<DrawData>& toDraw=toDrawQueue.at(i);

  135.                         DrawData& curdata=toDraw.front();


  136.                         int line=i%(TYPE_MAX/2);
  137.                         int column=drawrt.right/2*(i*2/TYPE_MAX);
  138.                         CString str;
  139.                         str.Format("%s 步数:%d",SORTNAME[i],curdata.step);
  140.                         MemDC.TextOut(column,blockheight*line,str);

  141.                         for(int j=0;j<curdata.data.size();j++)
  142.                         {
  143.                                 int num=curdata.data.at(j);
  144.                                
  145.                                 if(curdata.stress.count(j))
  146.                                 {
  147. //                                        MemDC.SelectObject(&stresspen);
  148.                                         MemDC.SelectObject(&stressbrush);
  149.                                         curdata.stress.erase(num);
  150.                                 }
  151.                                 else
  152.                                 {
  153. //                                        MemDC.SelectObject(&normalpen);
  154.                                         MemDC.SelectObject(&normalbrush);
  155.                                 }
  156.                                 MemDC.Rectangle(j*BARSIZE+column,blockheight*(line+1)-num,j*BARSIZE+BARSIZE+column,blockheight*(line+1));
  157.                         }       
  158.                        
  159.                         if(toDraw.size() > 1 && running)
  160.                                 toDraw.pop();
  161.                 }
  162.                 dc.BitBlt(0,0,drawrt.right,drawrt.bottom,&MemDC,0,0,SRCCOPY);

  163.                 MemDC.DeleteDC();
  164.                 MemBitmap.DeleteObject();
  165.         }
  166. }

  167. // The system calls this to obtain the cursor to display while the user drags
  168. //  the minimized window.
  169. HCURSOR CDrawsortDlg::OnQueryDragIcon()
  170. {
  171.         return (HCURSOR) m_hIcon;
  172. }

  173. DWORD WINAPI CalcThread(LPVOID lpParameter)
  174. {
  175.         CDrawsortDlg* dlg=(CDrawsortDlg*)lpParameter;
  176.         dlg->toDrawQueue.clear();
  177.         for(int l=0;l<TYPE_MAX;l++)
  178.         {
  179.                 dlg->toDrawQueue.push_back(queue<DrawData>());
  180.         }
  181.        
  182.         int sizeq=dlg->toDrawQueue.size();
  183.        
  184.         vector<int> data;
  185.         RECT drawrect;
  186.         dlg->m_draw.GetClientRect(&drawrect);
  187.         int blockheight=drawrect.bottom*2/dlg->toDrawQueue.size();
  188.         int num=drawrect.right/(2*dlg->m_blocksize.GetPos());
  189.         for(int i=0;i<num;i++)
  190.         {
  191.                 data.push_back(rand()%blockheight);
  192.         }
  193.        
  194.         dlg->MAOPAO(data);
  195.         dlg->MAOPAO1(data);
  196.         dlg->MAOPAO2(data);
  197.         dlg->KUAISU(data);
  198.         dlg->CHARU(data);
  199.         dlg->ERFENCHARU(data);
  200.         dlg->XIER(data);
  201.        
  202.         dlg->XUANZE(data);
  203.         dlg->JINBIAOSAI(data);
  204.         dlg->HEAP(data);
  205.         dlg->MERGE(data);
  206.         dlg->BUCKET(data);

  207.         return 0;
  208. };

  209. void CDrawsortDlg::OnDraw()
  210. {
  211.         CreateThread(NULL,0,CalcThread,this,0,NULL);
  212.         // TODO: Add your control notification handler code her
  213. }

  214. void CDrawsortDlg::OnTimer(UINT nIDEvent)
  215. {
  216.         // TODO: Add your message handler code here and/or call default
  217.         Invalidate(FALSE);

  218.         CDialog::OnTimer(nIDEvent);
  219. }


  220. void CDrawsortDlg::MAOPAO(const vector<int>& _data)
  221. {
  222.         vector<int> data=_data;
  223.         int step=0;
  224.         int size=data.size();

  225.         toDrawQueue.at(TYPE_MAOPAO).push(DrawData(data,set<int>(),step));

  226.         for(int i=size-1;i > 0;i--)
  227.         {
  228.                 step++;
  229.                 for(int j=0;j < i;j++)
  230.                 {
  231.                         step++;
  232.                         set<int> curset;
  233.                         curset.insert(size-j-1);
  234.                         curset.insert(size-j-2);
  235.                        
  236.                         if(data[size-j-1] < data[size-j-2])
  237.                         {
  238.                                 int tmp=data[size-j-1];
  239.                                 data[size-j-1]=data[size-j-2];
  240.                                 data[size-j-2]=tmp;
  241.                         }
  242.                         toDrawQueue.at(TYPE_MAOPAO).push(DrawData(data,curset,step));
  243.                 }
  244.         }

  245.         toDrawQueue.at(TYPE_MAOPAO).push(DrawData(data,set<int>(),step));
  246. }

  247. void CDrawsortDlg::MAOPAO1(const vector<int>& _data)
  248. {//设置哨兵位监视某个点之后不需要交换
  249.         vector<int> data=_data;
  250.         int step=0;
  251.         int size=data.size();


  252.         toDrawQueue.at(TYPE_MAOPAO1).push(DrawData(data,set<int>(),step));

  253.         for(int i=size-1;i > 0;i--)
  254.         {
  255.                 step++;
  256.                 int flag=0;
  257.                 for(int j=0;j < i;j++)
  258.                 {
  259.                         step++;
  260.                         set<int> curset;
  261.                         curset.insert(size-j-1);
  262.                         curset.insert(size-j-2);
  263.                        
  264.                         if(data[size-j-1] < data[size-j-2])
  265.                         {
  266.                                 int tmp=data[size-j-1];
  267.                                 data[size-j-1]=data[size-j-2];
  268.                                 data[size-j-2]=tmp;
  269.                                 flag=j;
  270.                         }
  271.                         toDrawQueue.at(TYPE_MAOPAO1).push(DrawData(data,curset,step));
  272.                 }
  273.                 i=flag+1;
  274.         }
  275.        
  276.         toDrawQueue.at(TYPE_MAOPAO1).push(DrawData(data,set<int>(),step));
  277. }

  278. void CDrawsortDlg::MAOPAO2(const vector<int>& _data)
  279. {//设置哨兵位监视不需要交换的位置,且进行双向冒泡排序
  280.         vector<int> data=_data;
  281.         int step=0;
  282.         int size=data.size();
  283.         int begin=0,end=size-1;

  284.         toDrawQueue.at(TYPE_MAOPAO2).push(DrawData(data,set<int>(),step));

  285.         while(begin < end)
  286.         {
  287.                 step++;
  288.                 int j;
  289.                 int flag;
  290.                 for(j=flag=end;j > begin;j--)
  291.                 {       
  292.                         step++;
  293.                         set<int> curset;
  294.                         curset.insert(j);
  295.                         curset.insert(j-1);

  296.                         if(data[j] < data[j-1])
  297.                         {
  298.                                 int tmp=data[j];
  299.                                 data[j]=data[j-1];
  300.                                 data[j-1]=tmp;
  301.                                 flag=j;
  302.                         }
  303.                         toDrawQueue.at(TYPE_MAOPAO2).push(DrawData(data,curset,step));
  304.                 }
  305.                 begin=flag;
  306.                
  307.                 for(j=flag=begin;j < end;j++)
  308.                 {               
  309.                         step++;
  310.                         set<int> curset;
  311.                         curset.insert(j);
  312.                         curset.insert(j+1);

  313.                         if(data[j+1] < data[j])
  314.                         {
  315.                                 int tmp=data[j+1];
  316.                                 data[j+1]=data[j];
  317.                                 data[j]=tmp;
  318.                                 flag=j;
  319.                         }
  320.                         toDrawQueue.at(TYPE_MAOPAO2).push(DrawData(data,curset,step));
  321.                 }
  322.                 end=flag;
  323.         }

  324.         toDrawQueue.at(TYPE_MAOPAO2).push(DrawData(data,set<int>(),step));
  325. }

  326. void CDrawsortDlg::KUAISU(const vector<int>& _data)
  327. {
  328.         vector<int> data=_data;
  329.         int step=0;
  330.         int size=data.size();
  331.        
  332.         toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,set<int>(),step));

  333.         stack<int> emulate;
  334.         emulate.push(0);
  335.         emulate.push(size-1);
  336.         set<int> curset;

  337.         while(!emulate.empty())
  338.         {
  339.                 step++;
  340.                 int finish=emulate.top();
  341.                 emulate.pop();
  342.                 int start=emulate.top();
  343.                 emulate.pop();
  344.                 int begin=start,end=finish;
  345.                 int tmp=data[begin];
  346.                
  347.                 while(begin < end)
  348.                 {
  349.                         step++;
  350.                         while(begin < end && data[end] >= tmp)
  351.                         {
  352.                                 end--;

  353.                                 step++;
  354.                                 curset.clear();
  355.                                 curset.insert(begin);
  356.                                 curset.insert(end);
  357.                                 toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,curset,step));
  358.                         }
  359.                         data[begin]=data[end];

  360.                         curset.clear();
  361.                         curset.insert(begin);
  362.                         curset.insert(end);                       
  363.                         toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,curset,step));


  364.                         while(begin < end && data[begin] <= tmp)
  365.                         {
  366.                                 begin++;

  367.                                 step++;
  368.                                 curset.clear();
  369.                                 curset.insert(begin);
  370.                                 curset.insert(end);
  371.                                 toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,curset,step));
  372.                         }
  373.                         data[end]=data[begin];

  374.                         curset.clear();
  375.                         curset.insert(begin);
  376.                         curset.insert(end);                       
  377.                         toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,curset,step));
  378.                 }

  379.                 data[begin]=tmp;
  380.                
  381.                 curset.clear();
  382.                 curset.insert(begin);
  383.                 curset.insert(end);                       
  384.                 toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,curset,step));

  385.                 if(start < begin-1)
  386.                 {
  387.                         emulate.push(start);
  388.                         emulate.push(begin-1);
  389.                 }
  390.                 if(finish > begin+1)
  391.                 {
  392.                         emulate.push(begin+1);
  393.                         emulate.push(finish);
  394.                 }
  395.                
  396.         }

  397.         toDrawQueue.at(TYPE_KUAISU).push(DrawData(data,set<int>(),step));
  398. }

  399. void CDrawsortDlg::CHARU(const vector<int>& _data)
  400. {
  401.         vector<int> data=_data;
  402.         int step=0;
  403.         int size=data.size();

  404.         toDrawQueue.at(TYPE_CHARU).push(DrawData(data,set<int>(),step));

  405.         for(int i=1;i<size;i++)
  406.         {//把i插入已排序的n-i+1的数组中进行排序
  407.                 int tmp=data[i];
  408.                
  409.                 if(tmp < data[i-1])
  410.                 {
  411.                         for(int j=i-1;j >= 0;j--)
  412.                         {
  413.                                 step++;
  414.                                 set<int> curset;
  415.                                 curset.insert(i);
  416.                                 curset.insert(j);

  417.                                 if(tmp<data[j])
  418.                                         data[j+1]=data[j];
  419.                                 else
  420.                                         break;

  421.                                 toDrawQueue.at(TYPE_CHARU).push(DrawData(data,curset,step));
  422.                         }
  423.                         data[j+1]=tmp;
  424.                 }
  425.         }

  426.         toDrawQueue.at(TYPE_CHARU).push(DrawData(data,set<int>(),step));
  427. }

  428. void CDrawsortDlg::ERFENCHARU(const vector<int>& _data)
  429. {
  430.         vector<int> data=_data;
  431.         int step=0;
  432.         int size=data.size();
  433.        
  434.         toDrawQueue.at(TYPE_ERFENCHARU).push(DrawData(data,set<int>(),step));

  435.         for(int i=1;i<size;i++)
  436.         {//把i插入已排序的n-i+1的数组中进行排序
  437.                 step++;

  438.                 int tmp=data[i];
  439.                
  440.                 if(tmp < data[i-1])
  441.                 {
  442.                         //在begin和end之间折半查找
  443.                         int begin=0;
  444.                         int end=i;
  445.                         int mid;
  446.                         while(begin < end)
  447.                         {
  448.                                 step++;
  449.                                 set<int> curset;
  450.                                 curset.insert(begin);
  451.                                 curset.insert(end);

  452.                                 mid=(begin+end)/2;
  453.                                 if(data[mid] < tmp)
  454.                                         begin=mid+1;
  455.                                 else if(data[mid] > tmp)
  456.                                         end=mid;
  457.                                 else
  458.                                         break;

  459.                                 toDrawQueue.at(TYPE_ERFENCHARU).push(DrawData(data,curset,step));
  460.                         }

  461.                         if(begin == end)
  462.                                 mid=begin;
  463.                        
  464.                         for(int j=i-1;j >= mid;j--)
  465.                         {
  466.                                 step++;
  467.                                 set<int> curset;
  468.                                 curset.insert(j);
  469.                                 curset.insert(j+1);

  470.                                 data[j+1]=data[j];

  471.                                 toDrawQueue.at(TYPE_ERFENCHARU).push(DrawData(data,curset,step));
  472.                         }
  473.                         data[j+1]=tmp;

  474.                         toDrawQueue.at(TYPE_ERFENCHARU).push(DrawData(data,set<int>(),step));
  475.                 }
  476.         }

  477.         toDrawQueue.at(TYPE_ERFENCHARU).push(DrawData(data,set<int>(),step));
  478. }

  479. void CDrawsortDlg::XIER(const vector<int>& _data)
  480. {
  481.         vector<int> data=_data;
  482.         int step=0;
  483.         int size=data.size();
  484.        
  485.         toDrawQueue.at(TYPE_XIER).push(DrawData(data,set<int>(),step));

  486.         int steparr[5]={1,5,19,41,109};//最优希尔步长
  487.         int stepindx=4;
  488.         while(stepindx)
  489.         {
  490.                 if(steparr[stepindx]*2 < size)
  491.                         break;
  492.                 stepindx--;
  493.         }
  494.        
  495.         while(stepindx >= 0)
  496.         {
  497.                 step++;
  498.                 int stepl=steparr[stepindx];
  499.                 for(int i=0;i<stepl;i++)
  500.                 {
  501.                         step++;
  502.                         for(int j=i+stepl;j < size;j += stepl)
  503.                         {//对{i,i+step,i+2step,....}插入排序
  504.                                 step++;
  505.                                 int tmp=data[j];
  506.                                 if(tmp < data[j-stepl])
  507.                                 {
  508.                                         int k=j-stepl;
  509.                                         while(k >= i)
  510.                                         {
  511.                                                 step++;
  512.                                                 set<int> curset;
  513.                                                 curset.insert(k);
  514.                                                 curset.insert(k+stepl);

  515.                                                 if(tmp < data[k])
  516.                                                         data[k+stepl]=data[k];
  517.                                                 else
  518.                                                         break;
  519.                                                 k -= stepl;

  520.                                                 toDrawQueue.at(TYPE_XIER).push(DrawData(data,curset,step));
  521.                                         }
  522.                                         data[k+stepl]=tmp;

  523.                                         toDrawQueue.at(TYPE_XIER).push(DrawData(data,set<int>(),step));
  524.                                 }
  525.                         }
  526.                 }
  527.                 stepindx--;
  528.         }

  529.         toDrawQueue.at(TYPE_XIER).push(DrawData(data,set<int>(),step));
  530. }

  531. void CDrawsortDlg::XUANZE(const vector<int>& _data)
  532. {
  533.         vector<int> data=_data;
  534.         int step=0;
  535.         int size=data.size();
  536.        
  537.         toDrawQueue.at(TYPE_XUANZE).push(DrawData(data,set<int>(),step));

  538.         for(int i=0;i<size;i++)
  539.         {
  540.                 step++;
  541.                 int minindx=i;
  542.                 for(int j=i+1;j<size;j++)
  543.                 {
  544.                         step++;
  545.                         set<int> curset;
  546.                         curset.insert(minindx);
  547.                         curset.insert(i);
  548.                         curset.insert(j);

  549.                         if(data[j] < data[minindx])
  550.                                 minindx=j;

  551.                         toDrawQueue.at(TYPE_XUANZE).push(DrawData(data,curset,step));
  552.                 }
  553.                 int tmp=data[i];
  554.                 data[i]=data[minindx];
  555.                 data[minindx]=tmp;

  556.                 toDrawQueue.at(TYPE_XUANZE).push(DrawData(data,set<int>(),step));
  557.         }

  558.         toDrawQueue.at(TYPE_XUANZE).push(DrawData(data,set<int>(),step));
  559. }

  560. void CDrawsortDlg::JINBIAOSAI(const vector<int>& _data)
  561. {
  562.         vector<int> data=_data;
  563.         int step=0;
  564.         int size=data.size();
  565.        
  566.         toDrawQueue.at(TYPE_JINBIAOSAI).push(DrawData(data,set<int>(),step));

  567.         int MAX=size;//只要不在数组索引中即可
  568.         vector<int> treedata;//二叉树
  569.         int volumn=2;
  570.        
  571.         while(volumn < size)
  572.                 volumn *= 2;
  573.        
  574.         int newsize=volumn-1+size;//计算完全二叉树容量
  575.        
  576.         vector<int> copydata;
  577.        
  578.         treedata.resize(newsize);
  579.         for(int i=0;i < volumn-1;i++)
  580.         {
  581.                 treedata[i]=MAX;
  582.         }
  583.        
  584.         for(i=0;i<size;i++)
  585.         {
  586.                 treedata[i+volumn-1]=i;
  587.         }
  588.        
  589.         //生成初始树  总长度为newsize
  590.         for(i=volumn-2;i >= 0;i--)
  591.         {
  592.                 step++;
  593.                 if(i*2+1 < newsize && treedata[i*2+1] != MAX)//有左子树且合法
  594.                 {//如果没有左子树,根据完全二叉树性质,肯定没有右子树,同理初始化时,如果左子树为MAX,那么右子树一定是MAX
  595.                         int tochange=i*2+1;
  596.                         if(i*2+2 < newsize && treedata[i*2+2] != MAX)//如果有右子树
  597.                         {
  598.                                 if(data[treedata[i*2+2]] < data[treedata[tochange]])
  599.                                         tochange=i*2+2;
  600.                         }
  601.                         treedata[i]=treedata[tochange];
  602.                 }
  603.         }
  604.        
  605.         int left=size;
  606.         while(left--) //做size次,每次从顶端取得最小值并相应吧索引值置为无效
  607.         {
  608.                 step++;
  609.                 copydata.push_back(data[treedata[0]]);
  610.                 int index=volumn-1+treedata[0];//索引位置
  611.                 treedata[index]=MAX;
  612.                 //从索引位置往父节点递归
  613.                 do
  614.                 {
  615.                         index = (index-1)/2;//得到父节点
  616.                         treedata[index]=MAX;//重置父节点
  617.                        
  618.                         set<int> curset;
  619.        
  620.                         if(index*2+1 < newsize)//有左子树
  621.                         {//仍然是如果没有左子树肯定没有右子树
  622.                                 int tochange=index*2+1;//可能为MAX
  623.                                 if(index*2+2 < newsize && treedata[index*2+2] != MAX)
  624.                                 {
  625.                                         if(treedata[tochange] == MAX ||
  626.                                                 (treedata[tochange] != MAX && data[treedata[tochange]] > data[treedata[index*2+2]]))
  627.                                                 tochange=index*2+2;

  628.                                         if(treedata[index*2+1] != MAX)
  629.                                         curset.insert(treedata[index*2+1]);
  630.                                         curset.insert(treedata[index+2+2]);
  631.                                 }
  632.                                 treedata[index]=treedata[tochange];//可能赋值为MAX
  633.                         }
  634.                        
  635.                         step++;
  636.                         vector<int> temp=copydata;
  637.                         //为了便于了解排序过程,这里将已经排出序的部分和其他部分进行组合
  638.                         for(int l=0;l<size;l++)
  639.                         {
  640.                                 if(treedata[l+volumn-1] != MAX)
  641.                                         temp.push_back(data[treedata[l+volumn-1]]);
  642.                         }
  643.                         toDrawQueue.at(TYPE_JINBIAOSAI).push(DrawData(temp,curset,step));
  644.                 }
  645.                 while(index);
  646.         }

  647.         data=copydata;

  648.         toDrawQueue.at(TYPE_JINBIAOSAI).push(DrawData(data,set<int>(),step));
  649. }

  650. void CDrawsortDlg::HEAP(const vector<int>& _data)
  651. {
  652.         vector<int> data=_data;
  653.         int step=0;
  654.         int size=data.size();
  655.        
  656.         toDrawQueue.at(TYPE_HEAP).push(DrawData(data,set<int>(),step));

  657.         int j;
  658.         set<int> curset;
  659.         //初始化大顶堆
  660.         for(int i=size/2-1;i >= 0;i--)
  661.         {//从最后节点的父节点往根节点遍历
  662.                 step++;

  663.                 while(2*i+1<size)
  664.                 {                       
  665.                         j=2*i+1;
  666.                         curset.clear();
  667.                         curset.insert(j);
  668.                         curset.insert(j+1);
  669.                         curset.insert(i);
  670.                        
  671.                         step++;
  672.                         toDrawQueue.at(TYPE_HEAP).push(DrawData(data,curset,step));

  673.                        
  674.                         if(j+1<size && data[j]<data[j+1])
  675.                                 j++;
  676.                         if(data[i] < data[j])
  677.                         {
  678.                                 int t=data[i];
  679.                                 data[i]=data[j];
  680.                                 data[j]=t;
  681.                                 i=j;
  682.                         }
  683.                         else
  684.                                 break;
  685.                 }
  686.         }
  687.        
  688.         for(i=size-1;i > 0;i--)
  689.         {//每次把大顶堆顶部最大值插在当前位置
  690.                 //交换最大值和当前位置
  691.                 int temp=data[i];
  692.                 data[i]=data[0];
  693.                 data[0]=temp;
  694.                 int k=0;
  695.                
  696.                 curset.clear();
  697.                 curset.insert(i);
  698.                 curset.insert(0);
  699.                
  700.                 step++;
  701.                 toDrawQueue.at(TYPE_HEAP).push(DrawData(data,curset,step));
  702.                 //调整堆使其为大顶堆
  703.                
  704.                 while(2*k+1<i)
  705.                 {
  706.                         j=2*k+1;

  707.                         curset.clear();
  708.                         curset.insert(j);
  709.                         curset.insert(j+1);
  710.                         curset.insert(k);
  711.                        
  712.                         step++;
  713.                         toDrawQueue.at(TYPE_HEAP).push(DrawData(data,curset,step));

  714.                         if(j+1<i && data[j]<data[j+1])
  715.                                 j++;
  716.                         if(data[k] < data[j])
  717.                         {
  718.                                 int t=data[k];
  719.                                 data[k]=data[j];
  720.                                 data[j]=t;
  721.                                 k=j;
  722.                         }
  723.                         else
  724.                                 break;
  725.                 }
  726.         }

  727.         toDrawQueue.at(TYPE_HEAP).push(DrawData(data,set<int>(),step));
  728. }

  729. void CDrawsortDlg::MERGE(const vector<int>& _data)
  730. {
  731.         vector<int> data=_data;
  732.         int step=0;
  733.         int size=data.size();
  734.        
  735.         toDrawQueue.at(TYPE_MERGE).push(DrawData(data,set<int>(),step));

  736.         set<int> curset;
  737.         vector<int> tmp;
  738.        
  739.         for(int stepl=1;stepl < size;stepl *= 2)
  740.         {
  741.                 int leftbegin,leftend,rightbegin,rightend;
  742.                 tmp.clear();
  743.                
  744.                 for(leftbegin=0;leftbegin < size;leftbegin =leftend+stepl+1)
  745.                 {//将[leftbegin,leftend]和[rightbegin,rightend]合并
  746.                         leftend=leftbegin+stepl-1;
  747.                         rightbegin=leftend+1;
  748.                         step++;
  749.                         if(rightbegin >= size)
  750.                         {
  751.                                 curset.clear();
  752.                                 while(leftbegin <= leftend)
  753.                                 {
  754.                                         step++;
  755.                                         curset.insert(leftbegin);
  756.                                         tmp.push_back(data[leftbegin++]);
  757.                                 }
  758.                                 toDrawQueue.at(TYPE_MERGE).push(DrawData(data,curset,step));

  759.                                 break;
  760.                         }
  761.                         rightend=rightbegin+stepl-1 < size-1?rightbegin+stepl-1:size-1;
  762.                         //归并

  763.                         curset.clear();
  764.                         while(leftbegin <= leftend && rightbegin <= rightend)
  765.                         {
  766.                                 step++;

  767.                                 curset.insert(leftbegin);
  768.                                 curset.insert(rightbegin);

  769.                                 if(data[leftbegin] > data[rightbegin])
  770.                                 {
  771.                                         tmp.push_back(data[rightbegin++]);
  772.                                 }
  773.                                 else
  774.                                 {
  775.                                         tmp.push_back(data[leftbegin++]);
  776.                                 }
  777.                         }
  778.                         if(leftbegin <= leftend)
  779.                         {
  780.                                 while(leftbegin <= leftend)
  781.                                 {
  782.                                         step++;
  783.                                         curset.insert(leftbegin);
  784.                                         tmp.push_back(data[leftbegin++]);
  785.                                 }
  786.                         }
  787.                         else
  788.                         {
  789.                                 while(rightbegin <= rightend)
  790.                                 {
  791.                                         step++;
  792.                                         curset.insert(rightbegin);
  793.                                         tmp.push_back(data[rightbegin++]);
  794.                                 }
  795.                         }

  796.                         toDrawQueue.at(TYPE_MERGE).push(DrawData(data,curset,step));
  797.                 }
  798.                
  799.                 data=tmp;
  800.                 toDrawQueue.at(TYPE_MERGE).push(DrawData(data,set<int>(),step));
  801.         }

  802.         toDrawQueue.at(TYPE_MERGE).push(DrawData(data,set<int>(),step));
  803. }

  804. void CDrawsortDlg::BUCKET(const vector<int>& _data)
  805. {
  806.         vector<int> data=_data;
  807.         int step=0;
  808.         int size=data.size();
  809.        
  810.         toDrawQueue.at(TYPE_BUCKET).push(DrawData(data,set<int>(),step));

  811. #define radix 16//根据桶排序算法可知复杂度为:log(radix,max{data})*(3*datasize+radix)
  812.         //在datasize为25-500,max{data}=100时,可以得到最优radix为16
  813.         int p[]={0,4,8,12};
  814. #define get_part(x,y) (x>>p[y]&radix-1)
  815.         vector<int> bucket;
  816.         bucket.resize(size);
  817.     int count[radix];

  818.         set<int> curset;
  819.        
  820.         int i,j;
  821.        
  822.     for(i=0;i<2;++i)
  823.     {
  824.                 step++;
  825.         memset(count,0,sizeof(int)*radix);
  826.                 curset.clear();
  827.                
  828.         for(j=0;j<size;++j)
  829.         {
  830.                         step++;
  831.             count[get_part(data[j],i)]++;
  832.         }
  833.                
  834.         for(j=1;j<radix;++j)
  835.         {
  836.                         step++;
  837.             count[j]+=count[j-1];
  838.         }
  839.                
  840.                 bucket=data;

  841.         for(j=size-1;j>=0;--j)
  842.         {
  843.                         step++;
  844.             int k=get_part(data[j],i);
  845.             bucket[count[k]-1]=data[j];
  846.             count[k]--;

  847.                         curset.insert(count[k]);
  848.                         toDrawQueue.at(TYPE_BUCKET).push(DrawData(bucket,curset,step));
  849.         }
  850.                
  851.                 data=bucket;

  852.                 toDrawQueue.at(TYPE_BUCKET).push(DrawData(data,set<int>(),step));
  853.     }
  854.        
  855.         toDrawQueue.at(TYPE_BUCKET).push(DrawData(data,set<int>(),step));
  856. }

  857. void CDrawsortDlg::OnCustomdrawVelocity(NMHDR* pNMHDR, LRESULT* pResult)
  858. {
  859.         // TODO: Add your control notification handler code here
  860.         KillTimer(1);
  861.         SetTimer(1,m_velocity.GetPos(),NULL);

  862.         *pResult = 0;
  863. }

  864. void CDrawsortDlg::OnGoon()
  865. {
  866.         // TODO: Add your control notification handler code here
  867.         running=true;
  868. }

  869. void CDrawsortDlg::OnPause()
  870. {
  871.         // TODO: Add your control notification handler code here
  872.         running=false;
  873. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2014-7-28 16:26:47 | 显示全部楼层
工程文件在群共享:drawsort.rar
qq群:1201120552

点评

喂!群号!  发表于 2014-7-28 17:00
回复 赞! 靠!

使用道具 举报

发表于 2014-7-28 17:01:10 | 显示全部楼层
我看到了歌词..
回复 赞! 靠!

使用道具 举报

发表于 2014-8-22 20:22:02 | 显示全部楼层
能把每种算法的思路逻辑详述一遍吗?看代码实在效率不高啊。
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-23 19:49 , Processed in 0.034936 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表