スタックソートのcとc++関数テンプレート(テンプレートクラスについて)
#include <iostream>
using namespace std;
const int maxn = 100;
void my_swap(int &a, int &b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
void heap_sort(int arr[],const int &len);
void heap_adjust(int arr[],int i,const int &len);
int main()
{
int i,len;//
int arr[maxn],tmp;
len = 0;
cout << " (-1 ):" << endl;
while(cin >> tmp)
{
if(tmp == -1)
break;
arr[len] = tmp;
len++;
}
heap_sort(arr,len);//
//
cout << " :" << endl;
for(i=0; i<len; i++)
cout << arr[i] << " ";//
cout << endl;
return 0;
}
void heap_sort(int arr[],const int &len)
{
int i;
for(i=len/2-1; i>=0; --i)// i = len/2 -1 , 。
{
heap_adjust(arr,i,len);
}//
// 0 len-1 , 0 ,
for(i=len-1; i>0; --i)
{
my_swap(arr[0],arr[i]);
heap_adjust(arr,0,i);// i
}
}
void heap_adjust(int arr[],int i,const int &len)
{
int lc;//
for(; i*2+1<len; i=lc)
{
lc = i*2+1;//
if(lc+1<len && arr[lc+1]>arr[lc])// ,
lc++;
if(arr[lc]>arr[i])//
my_swap(arr[lc],arr[i]);
else
break;//
}
}
/*
学習の心得:
1パラメータconst int&lenのサブ関数内で変化できない量;
パラメータint&aは、サブ関数では変更可能であり、主関数の数値である.
2スタックソートの定義:このシーケンスに格納されているベクトルarr[1..n]を完全な二叉木と見なす
のストレージ構造であれば、スタックは実質的に以下の性質を満たす完全な二叉木である.
いずれの非リーフノードのキーワードも、その左右の子供(存在する場合)より大きくない(または小さくない)
ノードのキーワード.
3山のソートも実は1種の選択ソートで、1種の木の形の選択ソートです;
従って、その最悪の場合、時間複雑度はnlognである.スタックソートは不安定なソートであり、記録の少ないソートには適していません.
*/
#include <iostream>
using namespace std;
const int maxn = 100;
typedef double TT;
template<typename T>
void my_swap(T &a, T &b)
{
T tmp;
tmp = a;
a = b;
b = tmp;
}
template<typename T>
void heap_sort(T arr[],const int &len);
template<typename T>
void heap_adjust(T arr[],int i,const int &len);
int main()
{
int i,len;//
TT arr[maxn],tmp;
len = 0;
cout << " (0 ):" << endl;
while(cin >> tmp)
{
if(tmp == '0' || tmp == 0)// 10
break;
arr[len] = tmp;
len++;
}
heap_sort(arr,len);//
//
cout << " :" << endl;
for(i=0; i<len; i++)
cout << arr[i] << " ";//
cout << endl;
return 0;
}
template<typename T>
void heap_sort(T arr[],const int &len)
{
int i;
for(i=len/2-1; i>=0; --i)// i = len/2 -1 , 。
{
heap_adjust(arr,i,len);
}//
// 0 len-1 , 0 ,
for(i=len-1; i>0; --i)
{
my_swap(arr[0],arr[i]);
heap_adjust(arr,0,i);// i
}
}
template<typename T>
void heap_adjust(T arr[],int i,const int &len)
{
int lc;//
for(; i*2+1<len; i=lc)
{
lc = i*2+1;//
if(lc+1<len && arr[lc+1]>arr[lc])// ,
lc++;
if(arr[lc]>arr[i])//
my_swap(arr[lc],arr[i]);
else
break;//
}
}
/*
学習の心得:
1テンプレートタイプパラメータは、キーワードclassまたはtypenameに識別子を付けて構成されます.
関数のテンプレートパラメータテーブルでは、この2つのキーワードの意味は同じです.これらは後の
パラメータ名は、潜在的な組み込みまたはユーザー定義のタイプを表します.
2関数テンプレートのインスタンス化は、パラメータがない場合は他の方法で決定する必要があります.
コンパイラがどの関数を使用するかを確認できるようにします(通常はテンプレートの実パラメータを表示します).
3関数テンプレートのフォーマットは次のとおりです.
template<パラメータ説明>
かんすうヘッド
かんすうたい
4もちろん、main関数ではテンプレートを作成できないようですが、この例はユーザーが選択することで実現できます.
char long int doubleなどの数値型タイプのソートは,ソートに>が用いられるためである.
*/