使用大堆和小堆实现从小到大排序,且空间开销为O(1)

来源:互联网 发布:java web环境搭建教程 编辑:程序博客网 时间:2024/04/30 06:49

大堆:

#include "heapSort.h"
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;

#define  ARRAY_SIZE 1000
int heapcount = 0;//记录总共的比较次数

void FixHeap(int L[], int Hsize, int root, int k){
 //int larger = 0;
 if((2 * (root + 1)) > Hsize)//叶子节点
  L[root] = k;
 else{
  int larger = 0;
  if((2*(root + 1)) == Hsize)//只有左子树
   larger = 2 * root + 1;
  else if(L[2 * root + 1] > L[2 * (root + 1)])//有左右子树
   larger = 2 * root + 1;
  else
   larger = 2 * (root + 1);
  if(k > L[larger])
  {
   heapcount++;
   L[root] = k;
  }
  else{
   heapcount++;
   L[root] = L[larger];
   FixHeap(L, Hsize, larger, k);
  }
 }
 return;
}

void BuildHeap(int L[], int n){
 for(int i = n/2 - 1; i >= 0; i--)// 从第n/2-1个节点开始向上建堆
  FixHeap(L, n, i, L[i]);
 return;
}

void HeapSort(int L[], int n ){
 BuildHeap(L, n);
 for(int i = n -1; i >= 0; i-- ){
  int temp = L[i];
  L[i] = L[0];
  FixHeap(L, i , 0, temp);
 }
 return;
}

void HeapSort_Write(){

 int sortArray[15];//存储每行读入的数据,用于排序算法的调用

 string strLine;
 char achLine[ARRAY_SIZE];
 const char* pchTok;

 ifstream in_file("original.txt", ios::in);
 ofstream out_file("heapResult.txt");
 
 int precount = 0;//用于和thiscount作差来计算每次排序所需要比较的次数
 int num = 0;//用来记录是第几行的排序结果

 while(in_file.good()){
  num++;
  //每次读一行并且拷贝到achLine中构成一个数组
  getline(in_file, strLine);
  strLine.copy(achLine, strLine.size(), 0);
  achLine[strLine.size()] = '/0';

  //每行中的元素以空格为标识断开转换为int类型后存入数组
  pchTok = strtok(achLine, " ");
  int i = 0;
  while((pchTok != NULL)){
   sortArray[i] = atoi(pchTok);
   i++;
   //cout << atoi(pchTok) << " ";
   pchTok = strtok(NULL, " ");
  }

  //使用堆排序算法并将结果,第几行的比较结果以及这一行排序所用的比较次数写入到heapResult.txt文件
  HeapSort(sortArray, 15);

  

  for(int j = 0; j < 15; j++){
   //setw的使用方法
   out_file << setw(3) << setiosflags(ios::right)<< sortArray[j]  ;//数组中的每个数都在一个3字符的宽的空间右对齐输出
  }

  int thiscount = heapcount;
  out_file << "第" << setw(4) << num << "行总共比较了" << setw(4) << thiscount - precount << "次" <<"排序结果是:" << "   ";
  precount = thiscount;

  
  out_file << endl;
 }
 //cout << endl;
 out_file.close();
 in_file.close();
}

/*************************************************************************/

小堆:

#include "tHeapSort.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

#define ARRAY_SIZE 1000
int tHeapcount = 0;//记录所有的比较次数

void tFixHeap(int L[], int Hsize, int root, int k ){
 //int larger = 0;
 if((2 * (root + 1)) > Hsize)//叶子节点,则跳过直接进行上一个非叶节点的调整
  L[root] = k;
 else{
  int smaller = 0;
  if((2*(root + 1)) == Hsize)//只有左子树,直接记录为较小位置的值
   smaller = 2 * root + 1;
  else if(L[2 * root + 1] < L[2 * (root + 1)])//有左右子树,则记录下较小的值的位置
  {
   smaller = 2 * root + 1;
  }
  else
  {
   smaller = 2 * (root + 1);
  }
  if(k < L[smaller]) {//如果已经是最小的元素则跳过直接进行上一个非叶节点的调整
   tHeapcount++;
   L[root] = k;
  }
  else{//若不是最小元素则选择较小的元素进行交换,并递归进行子堆的调整
   tHeapcount++;
   L[root] = L[smaller];
   tFixHeap(L, Hsize, smaller, k);
  }
 }
 return;
}

void tBuildHeap(int L[], int n){
 for(int i = n/2 - 1; i >= 0; i--)// 因为数组下标是从0开始的,所以从第n/2-1个节点开始向上建堆
  tFixHeap(L, n, i, L[i]);
 return;
}

void tHeapSort(int L[], int n ){

 for(int i = 0; i < n - 1; i++){//每次都删除堆顶的最小元素,然后对剩下的元素重建tHeap即可
  tBuildHeap(L + i, n - i);
 }

 /*for(int i = 0; i < 6; i++){//验证是否成功
 cout<<L[i]<<"  ";
 }*/

 return;
}

void tHeapSort_Write(){

 int sortArray[15];

 string strLine;
 char achLine[ARRAY_SIZE];
 const char* pchTok;

 ifstream in_file("original.txt", ios::in);
 ofstream out_file("tHeapResult.txt");

 int precount = 0;//用于和thiscount作差来计算每次排序所需要比较的次数
 int num = 0;//用来记录是第几行的排序结果

 while(in_file.good()){
  num++;
  //每次读一行并且拷贝到achLine中构成一个数组
  getline(in_file, strLine);
  strLine.copy(achLine, strLine.size(), 0);
  achLine[strLine.size()] = '/0';

  //每行中的元素以空格为标识断开转换为int类型后存入数组
  pchTok = strtok(achLine, " ");
  int i = 0;
  while((pchTok != NULL)){
   sortArray[i] = atoi(pchTok);
   i++;
   //cout << atoi(pchTok) << " ";
   pchTok = strtok(NULL, " ");
  }

  tHeapSort(sortArray, 15);

  int thiscount = tHeapcount;
  out_file << "   " << "第" << num << "行总共比较了" << thiscount - precount << "次" << "排序结果是:" << "   ";
  precount = thiscount;

  for(int j = 0; j < 15; j++){
   out_file << sortArray[j] << " ";
  }

  out_file << endl;
 }
 //cout << endl;
 out_file.close();
 in_file.close();


}

/***********************************************************************************/

#include "gerRanNum.h"
#include "heapSort.h"
#include "tHeapSort.h"
#include <iostream>
#include <iomanip>
using namespace std;

void main(){
 RanNum();
 HeapSort_Write();
 tHeapSort_Write();
}

原创粉丝点击