算法导论笔记(六) :桶排序及其C++实现

1 桶排序简介

与计数排序类似,桶排序也是对输入数据做了某种假设.因此运行的很快.

桶排序假设输入数据由一个随机过程产生.该过程将元素随机而独立的分布在[0,1)区间.

2 桶排序过程

(i) 将[0,1)区间划分为n个大小相同的区间(桶)

(ii)将各元素放入对应的桶中.

(iii)对每个桶里的元素进行排序

(vi)一次列出各个桶里的元素

下边是桶排序的一个实例:
算法导论笔记(六) :桶排序及其C++实现_第1张图片

3 完整代码

#ifndef __BUCKETSORT_H__
#define __BUCKETSORT_H__

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

struct Node
{
  float m_data;
  Node* m_next;
};

class BucketSort
{
  float* m_data;
  Node** m_bucket;
  int m_size;
  int m_num_bucket;
public:
  BucketSort(int size,int numBucket);
  ~BucketSort();
  void Create();
  void AddNode(float nodeValue);
  void CombineLists();
  void Sort();
  void Output();
  bool Verify();
};

#endif

#include "BucketSort.h"

BucketSort::BucketSort(int size,int numberBucket)
{
  m_size = size;
  m_num_bucket = numberBucket;
  m_data = (float*)malloc(sizeof(float)* size);
  m_bucket = (Node**)malloc(sizeof(Node*)*numberBucket);
}

BucketSort::~BucketSort()
{
  if(m_data)
  {
    free(m_data);
    Node* tmp;
    for(int i=0;i<m_num_bucket;i++)
    {
      Node* head = m_bucket[i];
      while(head)
      {
        tmp = head->m_next;
        free(head);
        head = tmp;
      }
      m_bucket[i] = NULL;
    }
  }
}

void BucketSort::Create()
{
  for(int i=0;i<m_num_bucket;i++)
  {
    m_bucket[i] = NULL;
  }
  srand((unsigned)time(NULL));
  for(int i=0;i< m_size;i++)
  {
    m_data[i] = (rand() % 1000) / (float)1000;  //只保留小数点后三位
  }
}

bool BucketSort::Verify()
{
  float oldValue = m_data[0];
  for(int i=1;i<m_size;i++)
  {
    if(m_data[i]<oldValue)
    {
      return false;
    }
    oldValue = m_data[i];
  }
  return true;
}

void BucketSort::CombineLists()
{
  Node* head;
  int index = 0;
  for(int i=0;i<m_num_bucket;i++)
  {
    head = m_bucket[i];
    while(head)
    {
      m_data[index++] = head->m_data;
      head = head->m_next;
    }
  }
}

void BucketSort::AddNode(float nodeValue)
{
  Node* pNode = (Node*)malloc(sizeof(Node));
  pNode->m_data = nodeValue;
  Node* head  = m_bucket[(int)(nodeValue * m_num_bucket)];
  Node* insertIndex = head;
  Node* lastNode;
  if(insertIndex == NULL)
  {
    m_bucket[(int)(nodeValue * m_num_bucket)] = pNode;
    pNode->m_next = NULL;
  }
  else
  {
    while(insertIndex)  //使用插入排序来排序桶内元素
    {
      if(nodeValue > insertIndex->m_data)
      {
        if(insertIndex->m_next == NULL)
        {
          insertIndex->m_next = pNode;
          pNode->m_next = NULL;
          break;
        }
        else
        {
          lastNode = insertIndex;
          insertIndex = insertIndex->m_next;
        }
      }
      else
      {
        if(insertIndex == head)
        {
          Node* tmp = head;
          head = pNode;
          pNode->m_next = tmp;
          m_bucket[(int)(nodeValue * m_num_bucket)] = head;
        }
        else
        {
          Node* tmp = insertIndex;
          lastNode->m_next = pNode;
          pNode->m_next = tmp;
        }
        break;
      }
    }
  }
}

void BucketSort::Sort()
{
  for(int i=0;i<m_size;i++)
  {
    AddNode(m_data[i]);
  }
  CombineLists();
}

void BucketSort::Output()
{
  for(int i=0;i<m_size;i++)
  {
    printf("%f \n",m_data[i]);
  }
}

#include "BucketSort.h"

int main()
{
  int size = 40;
  int bucket = 10;
  BucketSort pSort(size,bucket);
  pSort.Create();
  pSort.Output();
  pSort.Sort();
  if(pSort.Verify())
  {
    printf("Success! \n");
  }
  else
  {
    printf("Error! \n");
  }
  pSort.Output();
  return 0;
}


4 性能分析

桶排序的运行时间是O(n).

你可能感兴趣的:(C++,桶排序)