當前位置:首頁 » 操作系統 » 亂序演算法

亂序演算法

發布時間: 2022-08-15 03:30:56

Ⅰ 分布式系統中的RPC請求經常出現亂序的情況. 寫一個演算法來將一個亂序的序列保序輸出,求C語言大神

基本思想是將每一行存入一個鏈表結點,data表示起始數據,len表示每行元素個數。

structListNode
{
intdata;
intlen;
ListNode*next;
};

voidInsertNode(ListNode*&pHead,ListNode*pNode)
{
ListNode*pTmp=NULL;
if(pNode==NULL)
{
printf("pNodeisNULL! ");
return;
}
if(pHead==NULL)
{
pHead=pNode;
}
else
{
for(pTmp=pHead;pTmp->next!=NULL;pTmp=pTmp->next)
;
pTmp->next=pNode;
}
}


voidSortAndPrint(inta[],intn)
{
ListNode*pHead=NULL;
ListNode*temp=NULL;
inti=0;
intdata=0;
intdataLen=0;
while(i<n)
{
intj=0;
intlen=0;
intmoreNum=a[i];
intlessNum=a[i];

//查找小於一個數的連續數出現次數
while(j<i)
{
if(a[j]==lessNum-1)
{
j=0;
lessNum--;
continue;
}
j++;
}

//只有小於一個數的所有數均出現時才存數據
if(lessNum==1)
{
j=0;
while(j<i)
{
if(a[j]==moreNum+1)
{
len++;
moreNum++;
j=0;
continue;
}
j++;
}

ListNode*p=(ListNode*)malloc(sizeof(ListNode));
memset(p,0,sizeof(ListNode));
p->data=a[i];
p->len=len;
p->next=NULL;
InsertNode(pHead,p);
}
i++;
}

//按順序列印序列
for(temp=pHead;temp!=NULL;temp=temp->next)
{
dataLen=temp->len;
data=temp->data;
while(dataLen)
{
printf("%d,",data++);
dataLen--;
}
printf("%d ",data);
}

//釋放資源
ListNode*prev=NULL;
ListNode*curr=pHead;
while(curr!=NULL)
{
prev=curr;
curr=curr->next;
if(prev!=NULL)
{
free(prev);
prev=NULL;
}
}
}

intmain(void)
{
inta[]={1,2,5,8,10,4,3,6,9,7};
SortAndPrint(a,10);
return0;
}

Ⅱ C++中排序的演算法分析(文字分析)

排序演算法是一種基本並且常用的演算法。由於實際工作中處理的數量巨大,所以排序演算法對演算法本身的速度要求很高。
而一般我們所謂的演算法的性能主要是指演算法的復雜度,一般用O方法來表示。在後面我將給出詳細的說明。
對於排序的演算法我想先做一點簡單的介紹,也是給這篇文章理一個提綱。
我將按照演算法的復雜度,從簡單到難來分析演算法。
第一部分是簡單排序演算法,後面你將看到他們的共同點是演算法復雜度為O(N*N)(因為沒有使用word,所以無法打出上標和下標)。
第二部分是高級排序演算法,復雜度為O(Log2(N))。這里我們只介紹一種演算法。另外還有幾種演算法因為涉及樹與堆的概念,所以這里不於討論。
第三部分類似動腦筋。這里的兩種演算法並不是最好的(甚至有最慢的),但是演算法本身比較奇特,值得參考(編程的角度)。同時也可以讓我們從另外的角度來認識這個問題。
第四部分是我送給大家的一個餐後的甜點——一個基於模板的通用快速排序。由於是模板函數可以對任何數據類型排序(抱歉,裡面使用了一些論壇專家的呢稱)。

現在,讓我們開始吧:

一、簡單排序演算法
由於程序比較簡單,所以沒有加什麼注釋。所有的程序都給出了完整的運行代碼,並在我的VC環境
下運行通過。因為沒有涉及MFC和WINDOWS的內容,所以在BORLAND C++的平台上應該也不會有什麼
問題的。在代碼的後面給出了運行過程示意,希望對理解有幫助。
1.冒泡法:
這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡:
#include <iostream.h>
void BubbleSort(int* pData,int Count)
{
int iTemp;
for(int i=1;i<Count;i++)
{
for(int j=Count-1;j>=i;j--)
{
if(pData[j]<pData[j-1])
{
iTemp = pData[j-1];
pData[j-1] = pData[j];
pData[j] = iTemp;
}
}
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
BubbleSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
倒序(最糟情況)
第一輪:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,10,8,9->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:6次
其他:
第一輪:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交換2次)
第二輪:7,8,10,9->7,8,10,9->7,8,10,9(交換0次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
上面我們給出了程序段,現在我們分析它:這里,影響我們演算法性能的主要部分是循環和交換,
顯然,次數越多,性能就越差。從上面的程序我們可以看出循環的次數是固定的,為1+2+...+n-1。
寫成公式就是1/2*(n-1)*n。
現在注意,我們給出O方法的定義:
若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n) = O(g(n))。(呵呵,不要說沒
學好數學呀,對於編程數學是非常重要的!!!)
現在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)
=O(g(n))=O(n*n)。所以我們程序循環的復雜度為O(n*n)。
再看交換。從程序後面所跟的表可以看到,兩種情況的循環相同,交換不同。其實交換本身同數據源的有序程度有極大的關系,當數據處於倒序的情況時,交換次數同循環一樣(每次循環判斷都會交換),復雜度為O(n*n)。當數據為正序,將不會有交換。復雜度為O(0)。亂序時處於中間狀態。正是由於這樣的原因,我們通常都是通過循環次數來對比演算法。

2.交換法:
交換法的程序最清晰簡單,每次用當前的元素一一的同其後的元素比較並交換。
#include <iostream.h>
void ExchangeSort(int* pData,int Count)
{
int iTemp;
for(int i=0;i<Count-1;i++)
{
for(int j=i+1;j<Count;j++)
{
if(pData[j]<pData[i])
{
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
}
}
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
ExchangeSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
倒序(最糟情況)
第一輪:10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,9,10,8->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:6次
其他:
第一輪:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交換1次)
第二輪:7,10,8,9->7,8,10,9->7,8,10,9(交換1次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
從運行的表格來看,交換幾乎和冒泡一樣糟。事實確實如此。循環次數和冒泡一樣也是1/2*(n-1)*n,所以演算法的復雜度仍然是O(n*n)。由於我們無法給出所有的情況,所以只能直接告訴大家他們在交換上面也是一樣的糟糕(在某些情況下稍好,在某些情況下稍差)。
3.選擇法:
現在我們終於可以看到一點希望:選擇法,這種方法提高了一點性能(某些情況下)這種方法類似我們人為的排序習慣:從數據中選擇最小的同第一個值交換,在從省下的部分中選擇最小的與第二個交換,這樣往復下去。
#include <iostream.h>
void SelectSort(int* pData,int Count)
{
int iTemp;
int iPos;
for(int i=0;i<Count-1;i++)
{
iTemp = pData[i];
iPos = i;
for(int j=i+1;j<Count;j++)
{
if(pData[j]<iTemp)
{
iTemp = pData[j];
iPos = j;
}
}
pData[iPos] = pData[i];
pData[i] = iTemp;
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
SelectSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
倒序(最糟情況)
第一輪:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交換1次)
第二輪:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交換1次)
第一輪:7,8,9,10->(iTemp=9)7,8,9,10(交換0次)
循環次數:6次
交換次數:2次
其他:
第一輪:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交換1次)
第二輪:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交換1次)
第一輪:7,8,10,9->(iTemp=9)7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
遺憾的是演算法需要的循環次數依然是1/2*(n-1)*n。所以演算法復雜度為O(n*n)。
我們來看他的交換。由於每次外層循環只產生一次交換(只有一個最小值)。所以f(n)<=n
所以我們有f(n)=O(n)。所以,在數據較亂的時候,可以減少一定的交換次數。

4.插入法:
插入法較為復雜,它的基本工作原理是抽出牌,在前面的牌中尋找相應的位置插入,然後繼續下一張
#include <iostream.h>
void InsertSort(int* pData,int Count)
{
int iTemp;
int iPos;
for(int i=1;i<Count;i++)
{
iTemp = pData[i];
iPos = i-1;
while((iPos>=0) && (iTemp<pData[iPos]))
{
pData[iPos+1] = pData[iPos];
iPos--;
}
pData[iPos+1] = iTemp;
}
}

void main()
{
int data[] = {10,9,8,7,6,5,4};
InsertSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
倒序(最糟情況)
第一輪:10,9,8,7->9,10,8,7(交換1次)(循環1次)
第二輪:9,10,8,7->8,9,10,7(交換1次)(循環2次)
第一輪:8,9,10,7->7,8,9,10(交換1次)(循環3次)
循環次數:6次
交換次數:3次
其他:
第一輪:8,10,7,9->8,10,7,9(交換0次)(循環1次)
第二輪:8,10,7,9->7,8,10,9(交換1次)(循環2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)(循環1次)
循環次數:4次
交換次數:2次
上面結尾的行為分析事實上造成了一種假象,讓我們認為這種演算法是簡單演算法中最好的,其實不是,
因為其循環次數雖然並不固定,我們仍可以使用O方法。從上面的結果可以看出,循環的次數f(n)<=
1/2*n*(n-1)<=1/2*n*n。所以其復雜度仍為O(n*n)(這里說明一下,其實如果不是為了展示這些簡單
排序的不同,交換次數仍然可以這樣推導)。現在看交換,從外觀上看,交換次數是O(n)(推導類似
選擇法),但我們每次要進行與內層循環相同次數的『=』操作。正常的一次交換我們需要三次『=』
而這里顯然多了一些,所以我們浪費了時間。
最終,我個人認為,在簡單排序演算法中,選擇法是最好的。

二、高級排序演算法:
高級排序演算法中我們將只介紹這一種,同時也是目前我所知道(我看過的資料中)的最快的。
它的工作看起來仍然象一個二叉樹。首先我們選擇一個中間值middle程序中我們使用數組中間值,然後
把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對後交換)。然後對兩邊分別使
用這個過程(最容易的方法——遞歸)。
1.快速排序:
#include <iostream.h>
void run(int* pData,int left,int right)
{
int i,j;
int middle,iTemp;
i = left;
j = right;
middle = pData[(left+right)/2]; //求中間值
do{
while((pData[i]<middle) && (i<right))//從左掃描大於中值的數
i++;
while((pData[j]>middle) && (j>left))//從右掃描大於中值的數
j--;
if(i<=j)//找到了一對值
{
//交換
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
i++;
j--;
}
}while(i<=j);//如果兩邊掃描的下標交錯,就停止(完成一次)
//當左邊部分有值(left<j),遞歸左半邊
if(left<j)
run(pData,left,j);
//當右邊部分有值(right>i),遞歸右半邊
if(right>i)
run(pData,i,right);
}
void QuickSort(int* pData,int Count)
{
run(pData,0,Count-1);
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
QuickSort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
這里我沒有給出行為的分析,因為這個很簡單,我們直接來分析演算法:首先我們考慮最理想的情況
1.數組的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。
2.每次我們選擇的值剛好是中間值,這樣,數組才可以被等分。
第一層遞歸,循環n次,第二層循環2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以演算法復雜度為O(log2(n)*n)
其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那麼他將變
成交換法(由於使用了遞歸,情況更糟)。但是你認為這種情況發生的幾率有多大??呵呵,你完全
不必擔心這個問題。實踐證明,大多數的情況,快速排序總是最好的。
如果你擔心這個問題,你可以使用堆排序,這是一種穩定的O(log2(n)*n)演算法,但是通常情況下速度要慢於快速排序(因為要重組堆)。
三、其他排序
1.雙向冒泡:
通常的冒泡是單向的,而這里是雙向的,也就是說還要進行反向的工作。
代碼看起來復雜,仔細理一下就明白了,是一個來回震盪的方式。
寫這段代碼的作者認為這樣可以在冒泡的基礎上減少一些交換(我不這么認為,也許我錯了)。
反正我認為這是一段有趣的代碼,值得一看。
#include <iostream.h>
void Bubble2Sort(int* pData,int Count)
{
int iTemp;
int left = 1;
int right =Count -1;
int t;
do
{
//正向的部分
for(int i=right;i>=left;i--)
{
if(pData[i]<pData[i-1])
{
iTemp = pData[i];
pData[i] = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
left = t+1;
//反向的部分
for(i=left;i<right+1;i++)
{
if(pData[i]<pData[i-1])
{
iTemp = pData[i];
pData[i] = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
right = t-1;
}while(left<=right);
}
void main()
{
int data[] = {10,9,8,7,6,5,4};
Bubble2Sort(data,7);
for (int i=0;i<7;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
2.SHELL排序
這個排序非常復雜,看了程序就知道了。
首先需要一個遞減的步長,這里我們使用的是9、5、3、1(最後的步長必須是1)。
工作原理是首先對相隔9-1個元素的所有內容排序,然後再使用同樣的方法對相隔5-1個元素的排序
以次類推。
#include <iostream.h>
void ShellSort(int* pData,int Count)
{
int step[4];
step[0] = 9;
step[1] = 5;
step[2] = 3;
step[3] = 1;
int iTemp;
int k,s,w;
for(int i=0;i<4;i++)
{
k = step[i];
s = -k;
for(int j=k;j<Count;j++)
{
iTemp = pData[j];
w = j-k;//求上step個元素的下標
if(s ==0)
{
s = -k;
s++;
pData[s] = iTemp;
}
while((iTemp<pData[w]) && (w>=0) && (w<=Count))
{
pData[w+k] = pData[w];
w = w-k;
}
pData[w+k] = iTemp;
}
}
}
void main()
{
int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};
ShellSort(data,12);
for (int i=0;i<12;i++)
cout<<data[i]<<" ";
cout<<"\n";
}
呵呵,程序看起來有些頭疼。不過也不是很難,把s==0的塊去掉就輕松多了,這里是避免使用0
步長造成程序異常而寫的代碼。這個代碼我認為很值得一看。
這個演算法的得名是因為其發明者的名字D.L.SHELL。依照參考資料上的說法:「由於復雜的數學原因
避免使用2的冪次步長,它能降低演算法效率。」另外演算法的復雜度為n的1.2次冪。同樣因為非常復雜並
「超出本書討論范圍」的原因(我也不知道過程),我們只有結果了。

四、基於模板的通用排序:
這個程序我想就沒有分析的必要了,大家看一下就可以了。不明白可以在論壇上問。
MyData.h文件
///////////////////////////////////////////////////////
class CMyData
{
public:
CMyData(int Index,char* strData);
CMyData();
virtual ~CMyData();
int m_iIndex;
int GetDataSize(){ return m_iDataSize; };
const char* GetData(){ return m_strDatamember; };
//這里重載了操作符:
CMyData& operator =(CMyData &SrcData);
bool operator <(CMyData& data );
bool operator >(CMyData& data );
private:
char* m_strDatamember;
int m_iDataSize;
};
////////////////////////////////////////////////////////
MyData.cpp文件
////////////////////////////////////////////////////////
CMyData::CMyData():
m_iIndex(0),
m_iDataSize(0),
m_strDatamember(NULL)
{
}
CMyData::~CMyData()
{
if(m_strDatamember != NULL)
delete[] m_strDatamember;
m_strDatamember = NULL;
}
CMyData::CMyData(int Index,char* strData):
m_iIndex(Index),
m_iDataSize(0),
m_strDatamember(NULL)
{
m_iDataSize = strlen(strData);
m_strDatamember = new char[m_iDataSize+1];
strcpy(m_strDatamember,strData);
}
CMyData& CMyData::operator =(CMyData &SrcData)
{
m_iIndex = SrcData.m_iIndex;
m_iDataSize = SrcData.GetDataSize();
m_strDatamember = new char[m_iDataSize+1];
strcpy(m_strDatamember,SrcData.GetData());
return *this;
}
bool CMyData::operator <(CMyData& data )
{
return m_iIndex<data.m_iIndex;
}
bool CMyData::operator >(CMyData& data )
{
return m_iIndex>data.m_iIndex;
}
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//主程序部分
#include <iostream.h>
#include "MyData.h"
template <class T>
void run(T* pData,int left,int right)
{
int i,j;
T middle,iTemp;
i = left;
j = right;
//下面的比較都調用我們重載的操作符函數
middle = pData[(left+right)/2]; //求中間值
do{
while((pData[i]<middle) && (i<right))//從左掃描大於中值的數
i++;
while((pData[j]>middle) && (j>left))//從右掃描大於中值的數
j--;
if(i<=j)//找到了一對值
{
//交換
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
i++;
j--;
}
}while(i<=j);//如果兩邊掃描的下標交錯,就停止(完成一次)
//當左邊部分有值(left<j),遞歸左半邊
if(left<j)
run(pData,left,j);
//當右邊部分有值(right>i),遞歸右半邊
if(right>i)
run(pData,i,right);
}
template <class T>
void QuickSort(T* pData,int Count)
{
run(pData,0,Count-1);
}
void main()
{
CMyData data[] = {
CMyData(8,"xulion"),
CMyData(7,"sanzoo"),
CMyData(6,"wangjun"),
CMyData(5,"VCKBASE"),
CMyData(4,"jacky2000"),
CMyData(3,"cwally"),
CMyData(2,"VCUSER"),
CMyData(1,"isdong")
};
QuickSort(data,8);
for (int i=0;i<8;i++)
cout<<data[i].m_iIndex<<" "<<data[i].GetData()<<"\n";
cout<<"\n";
}

Ⅲ 把一個完全亂序的數列,用什麼排序演算法能最快的排列出來

一般情況,也就是這些數是隨機的,那麼可以是快速排序,堆排序,歸並排序,他們的演算法復雜度都是n*log2n(2是底數)

Ⅳ 如何實現hash排序演算法

不知道你在說什麼鳥語? hash的意思就是亂序,排序就是有序,你的問題等價於亂序有序演算法。亂序怎麼還能有序呢?

自己去網路一下hash排序這個詞,看看別人都是怎麼描述的吧,根本不是你這個意思。

Ⅳ 亂序執行的區別

亂序執行技術與順序執行技術
未來主流的計算市場(台式機、伺服器和筆記本電腦)需要的是有限多核架構,更加強調核的單線程性能,而很多核架構(數十甚至上百個內核)則將應用於流計算、HPC和SoC等特殊計算環境。這也將成為未來英特爾處理器的一個分水嶺,於是就有了所謂「大核」和「小核」處理器之分。前者以目前的酷睿架構為發展基準,追求更好的單線程性能; 後者則以凌動(Atom)內核為基礎,在設計上強調更高的並行度和更低的功耗。
在指令執行方面,「大核」採用的是亂序執行(out-of-order execution)模式,而「小核」則採用順序執行(In-order execution)模式。與順序執行相對應的亂序執行,是指CPU允許將多條指令不按程序規定的順序分開發送給各相應電路單元處理的技術。
對比
與順序執行技術相比,亂序執行能夠更有效地提高IPC,即提高每個時鍾頻率能夠執行的指令數量。一般來說在同樣一個主頻周期當中,無序核執行指令數量要比有序核執行的數量更多,因而亂序執行架構的處理器單核的計算能力比較強。但亂序執行模式的處理器在電路設計上比較復雜,核的功耗也比較高,在手機和某些嵌入式應用需要絕對低功耗的場合較難達到其設計要求,因此凌動處理器很自然地就採用了順序執行模式。
未來,很多核處理器和有限多核處理器將並行發展,以共同滿足日益分化和復雜的計算環境的需求。而評價一款處理器好壞的標准也會更加復雜,可能既不是通過主頻甚至也不是IPC,而要根據其應用特性來具體判斷。
亂序執行技術與龍芯2F晶元
應用
龍芯處理器在工業控制、PC、筆記本、軍工方面已經有非常成熟的應用,其實在某種意義上說,國產晶元已經進入了主流市場。據王成江先生透露,有很多政府以及軍隊都在長期使用龍芯平台。
對比
曙光千兆防火牆採用的是龍芯2F晶元,它是64位的通用RISC處理器,採用90nm的CMOS工藝製造,完全兼容MIPS 64標准。龍芯2F是基於龍芯2E處理器的改進版本,於2007年研製成功。龍芯2F集成了高性能龍芯2號CPU核,四發射動態超標量結構,9-10 級超流水線,支持寄存器重命名、動態調度、轉移預測等亂序執行技術;龍芯2F在龍芯2E的基礎上提高了I/O性能和內存訪問帶寬,集成內存控制器,提升了數據吞吐的速度,為網路安全產品提供了比較好的平台。
亂序執行技術與英特爾E8400處理器
簡介
45納米英特爾酷睿2雙核處理器E8400可為嵌入式應用提供長達7年的生命周期支持。這款處理器同時還支持英特爾可信執行技術(Intel Trusted Execution Technology),以幫助客戶部署安全的嵌入式解決方案。
增強的多媒體性能
該款45納米處理器中引入了超級亂序執行引擎,能夠增強專為圖形和多媒體處理優化的英特爾SIMD流指令擴展(SSE)演算法。超級亂序執行引擎能夠降低延遲,並在加快現有SSE指令運行速度的同時,顯著提升最新SSE4指令集的表現。開發人員可充分利用SSE4多媒體指令集,提升互動式客戶端或數字簽名等終端嵌入式應用內在的視頻編輯和編碼功能。
英特爾可信執行技術
英特爾可信執行技術是英特爾酷睿2雙核處理器E8400中的一項硬體延展技術,它將硬體數據安全性引入了嵌入式市場,使得雙核處理器成為了防務、政府、中型網路安全設備和零售應用的理想選擇。這項安全技術旨在保護虛擬化計算環境中的數據免遭軟體攻擊、病毒入侵及其它類型威脅。[6]
編輯本段
亂序執行技術與Intel的Nehalem架構晶元
建立
Nehalem還是基本建立在酷睿微架構(Core Microarchitecture)的骨架上,外加增添了SMT、3層Cache、TLB和分支預測的等級化、IMC、QPI和支持DDR3、新增加SSE4.2指令等技術。比起從Pentium 4的NetBurst架構到酷睿微架構的較大變化來說,從酷睿微架到Nehalem架構的基本核心部分的變化則要小一些,因為Nehalem還是4指令寬度的解碼/重命名/撤銷。
原因
Nehalem的亂序引擎顯著的擴大了,除了性能原因,還有就是為了提供SMT,因為SMT需要資源共享。
和酷睿 2一樣,Nehalem的寄存器重命名表(register alias table,RAT)指明每一個結構寄存器(architectural register)要麼進入重排序緩沖(Re-Order Buffer,ROB),要麼是進入撤銷寄存器文件(Retirement Register File,RRF,或翻譯為引退寄存器文件),並且保持有絕大多數最近的推測值狀態(speculative state)。而RRF則保持有絕大多數最近的非推測狀態(non-speculative state)。RAT可以每周期重命名4個微操作,給每一個微操作在ROB中一個目的地寄存器(destination register)。被重命名的指令就讀取它們的源操作數並被發送到通用架構的保留站(unified Reservation Station,RS,可以被各種指令類型使用)。
Nehalem的ROB(重排序緩沖)從96項增加到128項,RS(保留站)從32項增加到36項,它們都由兩個線程所共享,但是使用不同的策略。ROB是靜態分配給2個線程,使得2個線程在指令流里都可以預測得一樣遠。而RS則是競爭共享,基於各線程的需求。這是因為許多時候一個線程可能會中止,從內存等待操作數,而使用到很少的RS項。這樣就不如讓另一個更活躍的線程盡可能多地使用RS項。在RS中的指令當其所有操作數都准備好時,就被分配到執行單元去。
Nehalem的執行單元與酷睿 2相比,基本沒有大的改變,而且並不受SMT的影響,除了使用率更高之外。
編輯本段
亂序執行技術與威盛凌瓏(VIA Nano)處理器
簡介
威盛凌瓏(VIA Nano)處理器是威盛 x86 平台系列第一款 64 位的超標量亂序執行處理器,旨在激活傳統台式和筆記本 PC 市場,為廣為需求計算技術、娛樂和網路連接應用提供了真正優質性能。
威盛 C7系列處理器採用市場領先的節能科技,威盛凌瓏(VIA Nano)處理器系列在同一功耗范圍,把性能提高到原來的四倍,從而進一步提升了其每瓦性能值的領導地位。而與C7系列處理器相同的針腳兼容保證了OEM 和主板商能更平順地實現二者的轉換,另外,也讓現有系統和主板升級更易行。
威盛凌瓏(VIA Nano) 處理器系列
處理器名稱
型號
主頻
威盛 V4 前端匯流排
封裝
處理器製程
閑置功耗
VIA Nano
L2100
1.8GHz
800MHz
NanoBGA2
65nm
500mW
VIA Nano
L2200
1.6GHz
800MHz
NanoBGA2
65nm
100mW
VIA Nano
U2300
1.3+GHz
800MHz
NanoBGA2
65nm
100mW
VIA Nano
U2500
1.2GHz
800MHz
NanoBGA2
65nm
100mW
VIA Nano
U2400
1.0GHz
800MHz
NanoBGA2
65nm
100mW
關鍵架構性能
尺寸
威盛凌瓏(VIA Nano)處理器採用富士通先進的65納米處理器技術,實現了高性能和低功耗完美的融合。它進一步鞏固了威盛在處理器小型化的領導地位,通過超密集設計,實現了x86平台新一代更小型化設計和應用。
封裝尺寸:威盛凌瓏(VIA Nano)BGA2 封裝(21mm x 21mm)
核心尺寸:7.650mm x 8.275mm (63.3平方毫米)
64 位的超標量亂序執行的微體系結構
威盛凌瓏(VIA Nano)處理器支持完整 64 位指令集,具備宏融合 (Macro-Fusion),微融合 (micro-fusion)功能,和精密復雜的分支預測。進一步降低了處理器功耗,提升了其效能。
高性能計算和媒體處理
威盛凌瓏(VIA Nano)處理器支持高速、低功耗威盛V4 前端匯流排,最低為800 MHz,支持新的SSE指令、2個64KB L1 高速緩存和1MB獨立L2 高速緩存,具有 16路信道連接性能,實現了多媒體性能的一大飛躍。
特別值得一提的是,威盛凌瓏(VIA Nano)處理器在高性能浮點運算方面有了非常顯著的提升,使用了全新的浮點加法運演算法則,大大降低了 x86處理器中的浮點延遲時間(the lowest floating-point add latency),同樣,浮點乘法器也擁有了最低的浮點延遲時間。
換句話說,這意味著威盛凌瓏(VIA Nano)處理器提供了出色的流暢播放藍光碟和其它高清視頻格式的性能,它能解碼的媒體流速度可以達到40Mbps ,此外它獨有的雙時鍾浮點單元(FPU)和 128 位的數據通路,提供了絕佳的游戲體驗,提供了極順暢的 3D 圖片表現
下圖表明了威盛凌瓏(VIA Nano)處理器在計算方面優於廣受歡迎的 C7 處理器之處:
高級功耗和熱量管理
強勁的動態電源管理,包括支持新型「C6」電源狀態,PowerSaver科技,全新的電路設計和機制來管理晶元核心溫度,降低功耗提升了熱量管理水平。
通過處理器中的以上創新科技,威盛凌瓏(VIA Nano)處理器在擁有超標量結構,實現顯著的性能提升的同時,功耗卻能維持和之前的威盛 C7 系列 處理器一樣的范圍。
威盛 1.0 GHz 的凌瓏(VIA Nano) ULV 處理器的首樣產品最大的設計功耗(TDP)只有 5 瓦(空閑運行功耗只有100 毫瓦),而 1.8GHz 的威盛凌瓏(VIA Nano)處理器的功耗也只有 25.5 瓦(空閑運行功耗 500 毫瓦)。
威盛凌瓏(VIA Nano) 處理器計算性能雖增加,功耗仍維持不變,這進一步提升了每瓦性能值, 更始其成為業內每瓦性能值最佳的產品。
2007 上測試的性能總分
1.6GHz Celeron-M 的TDP(最大熱功耗) = 31瓦; 1.6GHz 威盛Nano 的TDP = 17 瓦
操作系統 = Windows Vista 企業版
可升級威盛 C7處理器:威盛凌瓏(VIA Nano)處理器與威盛 C7處理器家族產品針腳兼容,使 OEM 廠商和主板廠商能平順的進行新架構的產品交替,能讓他們僅需透過單一主板或系統設計,能擴展延伸到不同的市場領域中。
綠色科技:此外還完全符合 RoHS 標准和 WEEE 規則,產品無鹵素、無鉛,對保護環境和可持續計算科技大有裨益。
增強的威盛 PadLock安全引擎
威盛凌瓏(VIA Nano)處理器承繼了威盛處理器家族內核硬體加密加速器和安全特性,包括雙隨機數據生成器(RNG)、一個AES加密引擎、NX Bit 和一個處理 SHA-1/SHA-256 加密計算的安全混編引擎。
AMD Phenom Intel Core 2 Intel Atom VIA C7 VIA Nano
安全混編 No No No 完全 SHA-1 & SHA-256 完全 SHA-1 & SHA-256
緩沖區溢出 NX Bit NX Bit NX Bit NX Bit NX Bit
內核編密碼(On-Die Encryption) No No No 完全 AES 編/譯 acceleration RSA 加速 CBC, CFB-M, AC, CTR modes 25Gb/s 峰值 完全 AES 編/譯 acceleration RSA 加速CBC, CFB-M, AC, CTR modes 25Gb/s 峰值
隨機數字生成器(Random Number Generation) (RNG) No No No 2 個增強的硬體RNG ,Feeds輸出至SHA 引起的速度為 12Mb/s 2 個增強的硬體RNG ,Feeds輸出至SHA 引起的速度為 12Mb/s [7]
編輯本段
巴塞羅那新特性解析:堆棧操作與亂序執行
起源
Intel最早的Pentium M處理器引入了一項名為「dedicated stack manager」(專注堆棧管理器)的新特性,正如其名字所暗示的一樣,專注堆棧管理器專門處理所有的X86堆棧操作(例如push, pop, call, return等)。它將這些伐數據集中處理而無需其他執行單元參與,這尤其簡化了CPU整數執行單元的工作,加快了整數執行單元的處理速度。
技術
AMD在Barcelona中也引入了類似的技術,AMD稱之為Sideband Stack Optimizer(邊帶堆棧優化器)。有了邊帶堆棧優化器,處理器中的伐指令不再需要經過3路編碼,也不再由整數執行單元處理,這加快了堆棧的處理速度,也同時加快了整數執行單元的處理速度。
在Intel Core微構架中一個重要改進是OOOE亂序執行:當裝載指令隊列發生等待時,處理器可以將隊列後方處於等待的指令優先裝載並執行,而不是一直等待到堵塞結束。平均而言,約30%的指令會發生一定時間的堵塞,這一亂序執行模式的引入,使新構架CPU性能有了明顯的提高。AMD的K8構架並不支持OOOE亂序執行指令,所以即使K8構架有優秀的內置內存控制器,也依然被對手的Core構架擊敗。正視這一技術上的落後,AMD在K8L構架的首款晶元Barcelona上及時改進為OOOE技術,這一改進必將為K8L構架的性能帶來極大的提高。
Barcelona將可以亂序執行指令,同樣也可以在前一指令尚未處理完成時,裝載並用空載單元處理下一指令,即使這兩條指令需要讀取不同的內存地址。Barcelona擁有3個地址生成單元,可以完成3個寄存指令每周期,而Core構架每周期只能執行1次-K8L構架的寄存速度要比Core構架強大3倍。
K8L構架中加入了新的SSE4指令擴展:SSEEXTRQ/INSERTQ指令和MOVNTSD/MOVNTSS指令。前者可以將多條指令合並為一條指令執行,後者用來計算流量寄存指令。Intel也會將在稍候發布的Penryn處理器中加入。

Ⅵ 序號為1至n的n個人,分序號為1至n的n個物品,序號不重合的概率,的演算法

回答:
這個問題是一個經典問題,即「亂序問題」.
n個人分n個物品,不管序號重不重,共有n!種分法;
序號不重的分法共有d(n) = n!∑{i=0,n}[(-1)!/i!].
故序號不重的概率P(n)是
P(n) = d(n)/n!= ∑{i=0,n}[(-1)!/i!].

Ⅶ 排序演算法的復雜度

由於程序比較簡單,所以沒有加什麼注釋。所有的程序都給出了完整的運行代碼,並在我的VC環境
下運行通過。因為沒有涉及MFC和WINDOWS的內容,所以在BORLAND C++的平台上應該也不會有什麼
問題的。在代碼的後面給出了運行過程示意,希望對理解有幫助。 這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡: #include<iostream>usingnamespacestd;voidBubbleSort(int*pData,intCount){intiTemp;for(inti=0;i<Count;i++){for(intj=Count-1;j>i;j--){if(pData[j]<pData[j-1]){iTemp=pData[j-1];pData[j-1]=pData[j];pData[j]=iTemp;}}}}voidmain(){intdata[7]={10,9,8,7,6,5,4};BubbleSort(data,7);for(inti=0;i<7;i++){cout<<data[i]<<;}cout<<endl;system(PAUSE);}倒序(最糟情況)
第一輪:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,10,8,9->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:6次
其他:
第一輪:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交換2次)
第二輪:7,8,10,9->7,8,9,10->7,8,10,9(交換1次)
(這是原撰寫人的--7,8,10,9->7,8,10,9->7,8,10,9(交換0次),第二輪應該是這樣的)
第三輪:7,8,9,10->7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
上面我們給出了程序段,現在我們分析它:這里,影響我們演算法性能的主要部分是循環和交換,
顯然,次數越多,性能就越差。從上面的程序我們可以看出循環的次數是固定的,為1+2+...+n-1。
寫成公式就是1/2*(n-1)*n。
現在注意,我們給出O方法的定義:
若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n) = O(g(n))。(呵呵,不要說沒學好數學呀,對於編程數學是非常重要的!!!)
現在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)
=O(g(n))=O(n*n)。所以我們程序循環的復雜度為O(n*n)。
再看交換。從程序後面所跟的表可以看到,兩種情況的循環相同,交換不同。其實交換本身同數據源的
有序程度有極大的關系,當數據處於倒序的情況時,交換次數同循環一樣(每次循環判斷都會交換),
復雜度為O(n*n)。當數據為正序,將不會有交換。復雜度為O(0)。亂序時處於中間狀態。正是由於這樣的
原因,我們通常都是通過循環次數來對比演算法。 交換法的程序最清晰簡單,每次用當前的元素一一的同其後的元素比較並交換。 #include<iostream.h>voidExchangeSort(int*pData,intCount){intiTemp;for(inti=0;i<Count-1;i++){//共(count-1)輪,每輪得到一個最小值for(intj=i+1;j<Count;j++){//每次從剩下的數字中尋找最小值,於當前最小值相比,如果小則交換if(pData[j]<pData[i]){iTemp=pData[i];pData[i]=pData[j];pData[j]=iTemp;}}}}voidmain(){intdata[]={10,9,8,7,6,5,4};ExchangeSort(data,sizeof(data)/sizeof(int));for(inti=0;i<sizeof(data)/sizeof(int);i++){cout<<data[i]<<;}cout<<endl;system(PAUSE);}第一輪: 9,10,8,7->8,10,9,7->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,9,10,8->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:6次
其他:
第一輪:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交換1次)
第二輪:7,10,8,9->7,8,10,9->7,8,10,9(交換1次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
從運行的表格來看,交換幾乎和冒泡一樣糟。事實確實如此。循環次數和冒泡一樣
也是1/2*(n-1)*n,所以演算法的復雜度仍然是O(n*n)。由於我們無法給出所有的情況,所以
只能直接告訴大家他們在交換上面也是一樣的糟糕(在某些情況下稍好,在某些情況下稍差)。 現在我們終於可以看到一點希望:選擇法,這種方法提高了一點性能(某些情況下)
這種方法類似我們人為的排序習慣:從數據中選擇最小的同第一個值交換,在從剩下的部分中
選擇最小的與第二個交換,這樣往復下去。 #include<iostream.h>voidSelectSort(int*pData,intCount){intiTemp;intiPos;for(inti=0;i<Count-1;i++){iTemp=pData[i];iPos=i;for(intj=i+1;j<Count;j++){if(pData[j]<iTemp){iTemp=pData[j];iPos=j;}}pData[iPos]=pData[i];pData[i]=iTemp;}}voidmain(){intdata[]={10,9,8,7,6,5,4};SelectSort(data,7);for(inti=0;i<7;i++)cout<<data[i]<<;cout<< ;}倒序(最糟情況)
第一輪:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交換1次)
第二輪:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交換1次)
第一輪:7,8,9,10->(iTemp=9)7,8,9,10(交換0次)
循環次數:6次
交換次數:2次
其他:
第一輪:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交換1次)
第二輪:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交換1次)
第一輪:7,8,10,9->(iTemp=9)7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
遺憾的是演算法需要的循環次數依然是1/2*(n-1)*n。所以演算法復雜度為O(n*n)。
我們來看他的交換。由於每次外層循環只產生一次交換(只有一個最小值)。所以f(n)<=n
所以我們有f(n)=O(n)。所以,在數據較亂的時候,可以減少一定的交換次數。 插入法較為復雜,它的基本工作原理是抽出牌,在前面的牌中尋找相應的位置插入,然後繼續下一張 #include<iostream.h>voidInsertSort(int*pData,intCount){intiTemp;intiPos;for(inti=1;i<Count;i++){iTemp=pData[i];//保存要插入的數iPos=i-1;//被插入的數組數字個數while((iPos>=0)&&(iTemp<pData[iPos])){//從最後一個(最大數字)開始對比,大於它的數字往後移位pData[iPos+1]=pData[iPos];iPos--;}pData[iPos+1]=iTemp;//插入數字的位置}}voidmain(){intdata[]={10,9,8,7,6,5,4};InsertSort(data,7);for(inti=0;i<7;i++)cout<<data<<;cout<< ;}其他:
第一輪:8,10,7,9->8,10,7,9(交換0次)(循環1次)
第二輪:9,10,8,7->8,9,10,7(交換1次)(循環2次)
第一輪:8,9,10,7->7,8,9,10(交換1次)(循環3次)
循環次數:6次
交換次數:3次
其他:
第一輪:8,10,7,9->8,10,7,9(交換0次)(循環1次)
第二輪:8,10,7,9->7,8,10,9(交換1次)(循環2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)(循環1次)
循環次數:4次
交換次數:2次
上面結尾的行為分析事實上造成了一種假象,讓我們認為這種演算法是簡單演算法中最好的,其實不是,
因為其循環次數雖然並不固定,我們仍可以使用O方法。從上面的結果可以看出,循環的次數f(n)<=
1/2*n*(n-1)<=1/2*n*n。所以其復雜度仍為O(n*n)(這里說明一下,其實如果不是為了展示這些簡單
排序的不同,交換次數仍然可以這樣推導)。現在看交換,從外觀上看,交換次數是O(n)(推導類似
選擇法),但我們每次要進行與內層循環相同次數的『=』操作。正常的一次交換我們需要三次『=』
而這里顯然多了一些,所以我們浪費了時間。
最終,我個人認為,在簡單排序演算法中,選擇法是最好的。 高級排序演算法中我們將只介紹這一種,同時也是目前我所知道(我看過的資料中)的最快的。
它的工作看起來仍然象一個二叉樹。首先我們選擇一個中間值middle程序中我們使用數組中間值,然後
把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對後交換)。然後對兩邊分別使
用這個過程(最容易的方法——遞歸)。
1.快速排序://這段代碼編譯可以通過,一運行就出錯,內部的細節有些問題,我還沒找到解決方法。 #include<iostream.h>voidrun(int*pData,intleft,intright){inti,j;intmiddle,iTemp;i=left;j=right;middle=pData[left];do{while((pData[i]<middle)&&(i<right))//從左掃描大於中值的數i++;while((pData[j]>middle)&&(j>left))//從右掃描大於中值的數j--;if(i<=j)//找到了一對值{//交換iTemp=pData[i];pData[i]=pData[j];pData[j]=iTemp;i++;j--;}}while(i<=j);//如果兩邊掃描的下標交錯,就停止(完成一次)//當左邊部分有值(left<j),遞歸左半邊if(left<j)run(pData,left,j);//當右邊部分有值(right>i),遞歸右半邊if(right>i)run(pData,i,right);}voidQuickSort(int*pData,intCount){run(pData,0,Count-1);}voidmain(){intdata[]={10,9,8,7,6,5,4};QuickSort(data,7);for(inti=0;i<7;i++)cout<<data[i]<<;//原作者此處代碼有誤,輸出因為date[i],date數組名輸出的是地址cout<< ;}這里我沒有給出行為的分析,因為這個很簡單,我們直接來分析演算法:首先我們考慮最理想的情況
1.數組的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。
2.每次我們選擇的值剛好是中間值,這樣,數組才可以被等分。
第一層遞歸,循環n次,第二層循環2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以演算法復雜度為O(log2(n)*n)
其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那麼他將變
成交換法(由於使用了遞歸,情況更糟)。但是你認為這種情況發生的幾率有多大??呵呵,你完全
不必擔心這個問題。實踐證明,大多數的情況,快速排序總是最好的。
如果你擔心這個問題,你可以使用堆排序,這是一種不穩定的O(log2(n)*n)演算法,但是通常情況下速度要慢
於快速排序(因為要重組堆)。 雙向冒泡
通常的冒泡是單向的,而這里是雙向的,也就是說還要進行反向的工作。 #include<iostream.h>inlinevoidexchange(int*a,int*b){inttemp;temp=*a;*a=*b;*b=temp;}voidbubblesort(int*array,intnum){inti,j,k,flag=0;for(i=0;i<num;i++){printf(%d,array[i]);}printf( );for(i=0;i<num;i++){//所有數的個數為num個flag=0;for(j=i;j<num-i-1;j++){//每循環一次最底端的數的順序都會排好,所以初始時j=i;if(array[j]>array[j+1]){exchange(&array[j],&array[j+1]);flag=1;}}for(k=num-1-i-1;k>i;k--){//每循環一次最頂端的數據的順序也會排好,所以初始時k=num-i-2if(array[k]<array[k-1]){exchange(&array[k],&array[k-1]);flag=1;}}if(flag==0){//如果flag未發生改變則說明未發生數據交換,則排序完成return;}}}voidmain(){intdata[]={10,9,8,7,6,5,4,3,2,1,-10,-1};bubblesort(data,12);for(inti=0;i<12;i++)cout<<data<<;cout<< ;} 這個程序我想就沒有分析的必要了,大家看一下就可以了。不明白可以在論壇上問。
MyData.h文件
///////////////////////////////////////////////////////
class CMyData
{
public:
CMyData(int Index,char* strData);
CMyData();
virtual ~CMyData();
int m_iIndex;
int GetDataSize(){ return m_iDataSize; };
const char* GetData(){ return m_strDatamember; };
//這里重載了操作符:
CMyData& operator =(CMyData &SrcData);
bool operator <(CMyData& data );
bool operator >(CMyData& data );
private:
char* m_strDatamember;
int m_iDataSize;
};
////////////////////////////////////////////////////////
MyData.cpp文件
////////////////////////////////////////////////////////
CMyData::CMyData():
m_iIndex(0),
m_iDataSize(0),
m_strDatamember(NULL)
{
}
CMyData::~CMyData()
{
if(m_strDatamember != NULL)
delete[] m_strDatamember;
m_strDatamember = NULL;
}
CMyData::CMyData(int Index,char* strData):
m_iIndex(Index),
m_iDataSize(0),
m_strDatamember(NULL)
{
m_iDataSize = strlen(strData);
m_strDatamember = new char[m_iDataSize+1];
strcpy(m_strDatamember,strData);
}
CMyData& CMyData::operator =(CMyData &SrcData)
{
m_iIndex = SrcData.m_iIndex;
m_iDataSize = SrcData.GetDataSize();
m_strDatamember = new char[m_iDataSize+1];
strcpy(m_strDatamember,SrcData.GetData());
return *this;
}
bool CMyData::operator <(CMyData& data )
{
return m_iIndex<data.m_iIndex;
}
bool CMyData::operator >(CMyData& data )
{
return m_iIndex>data.m_iIndex;
}
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//主程序部分
#include <iostream.h>
#include MyData.h
template <class T>
void run(T* pData,int left,int right)
{
int i,j;
T middle,iTemp;
i = left;
j = right;
//下面的比較都調用我們重載的操作符函數
middle = pData[(left+right)/2]; //求中間值
do{
while((pData<middle) && (i<right))//從左掃描大於中值的數
i++;
while((pData[j]>middle) && (j>left))//從右掃描大於中值的數
j--;
if(i<=j)//找到了一對值
{
//交換
iTemp = pData;
pData = pData[j];
pData[j] = iTemp;
i++;
j--;
}
}while(i<=j);//如果兩邊掃描的下標交錯,就停止(完成一次)
//當左邊部分有值(left<j),遞歸左半邊
if(left<j)
run(pData,left,j);
//當右邊部分有值(right>i),遞歸右半邊
if(right>i)
run(pData,i,right);
}
template <class T>
void QuickSort(T* pData,int Count)
{
run(pData,0,Count-1);
}
void main()
{
CMyData data[] = {
CMyData(8,xulion),
CMyData(7,sanzoo),
CMyData(6,wangjun),
CMyData(5,VCKBASE),
CMyData(4,jacky2000),
CMyData(3,cwally),
CMyData(2,VCUSER),
CMyData(1,isdong)
};
QuickSort(data,8);
for (int i=0;i<8;i++)
cout<<data.m_iIndex<< <<data.GetData()<< ;
cout<< ;

熱點內容
安卓網路編程怎麼用 發布:2025-01-16 03:04:45 瀏覽:899
湖南it伺服器怎麼樣 發布:2025-01-16 03:01:01 瀏覽:248
圖中兩種配置哪個好 發布:2025-01-16 02:59:28 瀏覽:582
如何解開密保密碼 發布:2025-01-16 02:57:44 瀏覽:23
中國銀行查詢密碼是什麼 發布:2025-01-16 02:33:20 瀏覽:794
堅果pro錄音文件夾 發布:2025-01-16 02:31:46 瀏覽:942
支付寶的登錄密碼忘記了如何改 發布:2025-01-16 02:30:30 瀏覽:224
解壓作業泥 發布:2025-01-16 02:28:02 瀏覽:810
我的世界rpg伺服器空島 發布:2025-01-16 02:26:49 瀏覽:93
ps腳本函數 發布:2025-01-16 02:15:28 瀏覽:484