1. 程式人生 > >基本演算法(一)-插入排序 InsertSort的C++實現

基本演算法(一)-插入排序 InsertSort的C++實現

    插入排序是最直接的排序方式之一,Algorithms.4 中舉例為抓撲克牌時,從左到右將最小的撲克牌放置在最左,依次進行。

void vInsertSort(vector<int> &nums){
	int len = nums.size();
	int temp;
	for(int i=0; i<len-1; i++){     // i從第一個到倒數第二個
		for(int j=i+1; j<len; j++){    // j從i後一個到最後一個,即遍歷無序區
			if(nums[j]<nums[i]){   // 不斷交換,最終每個i處都是第i小的數
				temp = nums[j];
				nums[j] = nums[i];
				nums[i] = temp;
			}
		}
	}
}

具體實現方法多種多樣,針對這段code,注意到i從0->length-1,即在倒數第二個即完成。如果為i<len,會導致j=i+1越界。(也可以使得j=i開始防止錯誤。上述code只是我因為這是最易於直觀理解的寫法,即每個元素i開始,與之後的所有元素比較並適時交換)。

完整的(更囉嗦的)程式碼見下:

#include <iostream>
#include <vector>

using namespace std;

// 迭代vector輸出每個元素
void coutAll(vector<int> &nums){
    vector<int>::iterator it;
    for(it=nums.begin(); it!=nums.end(); it++)
        cout<<*it<<" ";
    cout<<endl<<endl;;
}


// 返回排序的陣列並且不改變原資料
vector<int> InsertSort(vector<int> &nums){

    vector<int> sortedNum(nums);
	int len = sortedNum.size();
	int temp;
	for(int i=0; i<len-1; i++){     // i只從0到倒數第二個位置遍歷即可。
		for(int j=i+1; j<len; j++){     // j從i往後開始遍歷
		    // bool ii = sortedNum[j] < sortedNum[i];
            // cout<<sortedNum[j]<<" less "<<sortedNum[j-1]<<" is "<<ii<<endl; // 輸出每次比較的情況
			if(sortedNum[j]<sortedNum[i]){   // 交換,最終使得餘下最小的數處於i處
				temp = sortedNum[j];
				sortedNum[j] = sortedNum[i];
				sortedNum[i] = temp;
			}
        // coutAll(sortedNums);
		}
	}
	cout<<endl<<"Insert Sorted nums:"<<endl;
	coutAll(sortedNum); // 輸出排序後的結果

	return sortedNum;
}

// 對nums排序
void vInsertSort(vector<int> &nums){
	int len = nums.size();
	int temp;
	for(int i=0; i<len-1; i++){     // i只從0到倒數第二個位置遍歷即可。
		for(int j=i+1; j<len; j++){     // j從i往後開始遍歷
			if(nums[j]<nums[i]){   // 交換,最終使得餘下最小的數處於i處
				temp = nums[j];
				nums[j] = nums[i];
				nums[i] = temp;
			}
		}
	}
}


int main()
{
	int num7[7] = {2, 1, 5, 22, 13, -4, 5};
	vector<int> nums(&num7[0], &num7[6]);

	cout<<"Original nums: "<<endl;
	coutAll(nums);

	vector<int> sortedNum = InsertSort(nums); // 此處得到排序陣列sortedNum,且不改變nums的原來的值

    cout<<"Original nums: "<<endl;
    coutAll(nums);

    vInsertSort(nums);  // 該種方法即直接對nums排序
    cout<<"Original nums after vInsertSort(nums): "<<endl;
    coutAll(nums);

	return 0;
}

包含了InsertSort和vInsertSort,前者帶返回值,返回一個排序陣列且不改變原陣列,另一種不用新建陣列的方法即傳參時傳入vector<int> nums,但是耗時會多幾倍。後者無返回值,直接對陣列排序。具體見執行結果。