1. 程式人生 > >常見幾個排序原始碼及二分查詢原始碼

常見幾個排序原始碼及二分查詢原始碼


void swap(int &a, int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

//不使用中間變數的swap函式 

void swap_novar(int &a, int &b)
{
	if (a != b)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
}
//快排演算法實現1
int Median3(int *a, int left, int right)
{
	int center = (left + right)/2;
	if(a[left] > a[center])
		swap(a[left], a[center]);
	if(a[left] > a[right])
		swap(a[left], a[right]);
	if(a[center] > a[right])
		swap(a[center], a[right]);
		
	swap(a[center], a[right-1]);
	return a[right-1];
}

void Qsort1(int *a, int left, int right)
{
	if(left >= right)
		return;

	int pivot = Median3(a, left, right);
	int i = left, j = right-1;
			
	while(1)
	{
		while(a[++i] < pivot);
		while(a[--j] > pivot);
		
		if(i < j)
			swap(a[i], a[j]);
		else
			break;
	}
	swap(a[i], a[right-1]);


	Qsort1(a, left, i-1);
	Qsort1(a, i+1, right);
}

//快排演算法實現2
void Qsort2(int *a, int left, int right)
{
	if(left < right)
	{
		int pivot = a[left];
		
		int i = left, j = right;
	
		while(i < j)
		{
			while(i < j && a[j] >= pivot)
				j--;
			if(i < j)
				a[i++] = a[j];
		
			while(i < j && a[i] < pivot)
				i++;
			if(i < j)
				a[j--] = a[i];
		}
		a[i] = pivot;
		
		Qsort2(a, left, i-1);
		Qsort2(a, i+1, right);
	}
}

//堆排序 

//堆向上調整,堆插入新元素時呼叫 
//新插入元素在堆末尾,也就是下標為n-1處 
//向上調整操作與堆排序無關
void MaxHeapFixUp(int a[], int n)
{
	
	int i = n - 1;
	int tmp = a[i];
	int father = (i - 1)/2;
	
	while(father >= 0 && i != 0)
	{
		if(a[father] > tmp)
			break;
		
		a[i] = a[father];
		
		i = father;
		father = (i - 1) / 2;
	}
	a[i] = tmp;
}

//最大堆向下調整,刪除堆頂元素時呼叫(堆排序時使用) 
void MaxHeapFixDown(int a[], int i, int n)
{
	int tmp = a[i];
	int lchild = 2*i + 1;
	
	while(lchild < n)
	{
		if( (lchild+1) < n && a[lchild] < a[lchild + 1])
			lchild++;
			
		if(a[lchild] < tmp)
			break;	
			
		a[i] = a[lchild];


		i = lchild;
		lchild = 2*i + 1;
	}
	a[i] = tmp;
}

//建最大堆
void MakeMaxHeap(int a[], int n)  
{  
	int i;
    for (i = n/2 - 1; i >= 0; i--)
        MaxHeapFixDown(a, i, n);
}  

//堆排序

void HeapSort(int a[], int n)
{
	MakeMaxHeap(a, n);
	
	int i = n-1;
	for(i = n-1; i > 0; --i)
	{
		swap(a[0], a[i]);
		MaxHeapFixDown(a, 0, i);
	}
}

//氣泡排序

void BubbleSort(int a[], int n)
{
	int i, j;
	
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n-i; j++)
		{
			if(a[j] > a[j+1])
				swap(a[j], a[j + 1]);
		}
	}
}

//新增標記flag,當序列已經全部有序後提前結束
void BubbleSort2(int a[], int n)
{
	int flag = 1;	
	while(flag)
	{
		flag = 0;
		for(int j = 0; j < n; j++)
		{
			if(a[j] > a[j+1])
			{
				swap(a[j], a[j + 1]);
				flag = 1;
			}
		}
		n--;
	}
}

//直接插入排序(Insertion Sort):
//每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中的適當位置,直到全部記錄插入完成為止。
void InsertSort(int a[], int n)
{
	int i = 0;
	for(i = 1; i < n; i++)
	{
		int tmp = a[i];
		int j = i - 1;
		while(j >= 0 && a[j] > tmp)
		{
			a[j+1] = a[j];
			j--;
		}
		a[j+1] = tmp;
	}
}

//希爾排序:先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。 
void ShellSort(int a[], int n)
{
	int gap, i, j;
	for(gap = n/2; gap > 0; gap /= 2)
	{
		for(i = 0; i < gap; i++)
		{
			for(j = i + gap; j < n; j += gap)
			{
				int tmp = a[j];
				int k = j - gap;
				while(k >= 0 && a[k] > tmp)
				{
					a[k + gap] = a[k];
					k -= gap;
				}
				a[k + gap] = tmp;
			}
		}
	}
}

//直接選擇排序
void SelectSort(int a[], int n)
{
	int i, j;
	for(i = 0; i < n; ++i)
	{
		int min = a[i], k = i;
		for(j = i + 1; j < n; j++)
		{
			if(a[j] < min)
			{
				min = a[j];
				k = j;
			}
		}
		swap(a[i], a[k]);
	}
} 

//歸併排序
void merge(int a[], int tmparray[], int lpos, int rpos, int rightend)
{
	int leftend = rpos -  1;
	int tmppos = lpos;
	int num = rightend - lpos + 1;
	int i;
	while(lpos <= leftend && rpos <= rightend)
	{
		if(a[lpos] < a[rpos])
			tmparray[tmppos++] = a[lpos++];
		else
			tmparray[tmppos++] = a[rpos++];
	}	
	while(lpos <= leftend)
		tmparray[tmppos++] = a[lpos++];
	while(rpos <= rightend)
		tmparray[tmppos++] = a[rpos++];			

	for(i = 0; i < num; ++i, rightend--)
	{
		a[rightend] = tmparray[rightend];
	}
}

void Msort(int a[], int tmparray[], int left, int right)
{
	int mid;
	if(left < right)
	{
		mid = (left + right)/2;
		Msort(a, tmparray, left, mid);
		Msort(a, tmparray, mid + 1, right);
		merge(a, tmparray, left, mid + 1, right);
	}
}

void MergeSort(int a[], int n)
{
	int *tmparray = (int *)malloc(sizeof(int) * n);
	if(tmparray != NULL)
	{
		Msort(a, tmparray, 0, n-1);
		free(tmparray);
	}
}

二分查詢原始碼:

int binary_search(int array[], int n, int value)
{
	int left = 0;
	int right = n-1;
	while(left <= right)
	{
		int mid = left + ((<span style="color:#ff0000;">unsigned int</span>(right - left))>>1); //凡是右移操作時,一定要考慮有符號數符號擴充套件的問題
		if(array[mid] > value)
		{
			right = mid - 1;
		}
		else if(array[mid] < value)
		{
			left = mid + 1;
		}
		else
			return mid;
	}
	return -1;
}


相關推薦

常見排序原始碼二分查詢原始碼

void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } //不使用中間變數的swap函式  void swap_novar(int &a, int &b) { if (a

javascript常用陣列排序二分查詢

1. 氣泡排序 基本思路:依次比較相鄰的兩個數的大小,若大數在前、小數在後,則交換兩個數的位置,依次比較直至全部資料從小到大排好序 function sort_bubble(arr) { var len = arr.length; for (var i = 0;

CRC16常見標準的演算法C語言實現

CRC16常見的標準有以下幾種,被用在各個規範中,其演算法原理基本一致,就是在資料的輸入和輸出有所差異,下邊把這些標準的差異列出,並給出C語言的演算法實現。CRC16_CCITT:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在後,結果與0

用C語言實現常見排序方法

//排序方法通過 (函式呼叫) 的方式實現 //(1)直接插入排序 /* #include <stdio.h> #define N 100 void Insertsort(int data[],int n)  //實現插入排序方法: { int i,j,temp

排序查詢前N最大數和二分查詢演算法

先了解堆排序概念:堆排序利用了大根堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特徵,使得在當前無序區中選取最大(或最小)關鍵字的記錄變得簡單。 (1)用大根堆排序的基本思想 ① 先將初始檔案R[1..n]建成一個大根堆,此堆為初始的無序區 ② 再將關鍵字最大的記

Linux命令指令碼使用中的奇淫巧技

例項1.建立一個別名,刪除原始檔案,同時在使用者的home目錄下backup中儲存副本。 #/bin/bash cp [email protected] ~/backup && rm -rf [email protected] 例項2.For

【JS】 搜尋旋轉排序陣列 #陣列 #二分查詢

假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。 ( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。 搜尋一個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1 。 你可以假設陣列中不存在重複的元素。 你的

關於inflate的方法解析(結合日誌原始碼

inflate使我們使用頻率極高的api了,並且他有多個過載的方法,如下: View inflate(int, ViewGroup) View inflate(XmlPullParser, ViewGroup) View inflate(int, ViewGroup, b

排序優化與排序演算法時間複雜度

我們通常所說的堆是指二叉堆,二叉堆又稱完全二叉樹或者叫近似完全二叉樹。二叉堆又分為最大堆和最小堆。 堆排序(Heapsort)是指利用堆這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。陣列可以根據索引直接獲取元素,時間複雜度為O(1),也就是常量,因此對於取

折半查詢演算法二分查詢函式猜數字遊戲實現

折半查詢演算法 #include<stdio.h> int main() {     int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };     int left = 0;     int right = siz

資料庫概念關係型資料庫和非關係型資料庫的優缺點

幾個概念:     資料:能夠輸入到計算機中並被識別處理的資訊的集合     資料結構:組成一個數據集合的資料之間的關係     資料庫:按照一定的資料結構,儲存資料的倉庫。資料庫是在資料庫管理系統管理和控制下,在一定介質上的資料集合     資料庫管理系統:資料庫管理軟體,

Go語言學習筆記之簡單的排序

1.實現一個插入排序 核心思路是抽到的牌與前面的牌進行比較,如果抽到的牌小,那麼就互相交換位置.(正序排列) 1: func insert_sort(a []int) []int { 2: for i:=1;i<len(a);i++ { 3: for j:=i;j>0

列表查詢二分查詢 列表查詢以及二分查詢

列表查詢以及二分查詢 一、列表查詢 1、列表查詢:從列表中查詢指定元素 輸入:列表、待查詢元素 輸出:元素下標或未查詢到元素 2、順序查詢:從列表第一個元素開始,順序進行搜尋,直到找到為止。返回找到的那個索引 3、二分查詢:從有序列表

java面試中可能常問的技術問題答案

string和stringBuffer的區別; a.      常量和變數的區別,string雖然可以在後面增加其他字串,但是增加後就成了另一個物件,所以是個常量,stringBuffer字串改變後; b.     當字串需要經常改變的時候,一般用StringBuffer,

虛擬機器安裝遇到的小問題解決方法

1.必須注意硬碟預留100G空間==,慘痛遭遇不忍贅述。 2.安裝時提示缺失vmnetBridge.dll,下載可得。vmnetbridge.dll是屬於VMware Workstation虛擬機器軟體中的一個重要dll檔案,用於建立虛擬網路橋接時的資料檔案。

C語言排序函式和二分查詢呼叫方法

程式設計時經常遇到對陣列排序或在一個數組中查詢數字的情況,C庫<stdio.h>中提供了簡便的呼叫方法,將排序演算法封裝成通用的排序函式; 排序函式qsort void qsort( void *base, size_t n, size_t siz

分享開源的android專案的原始碼,基本上用androidstudio都可以編譯成功

轉自:http://blog.csdn.net/liuqz2009/article/details/53507472 Android開源專案有很多,但是完整的app專案不多,下面是最近我從 jcodecraeer網站 整理的一些開源app專案: 注: jcodecr

正確理解二分查詢

二分查詢 二分查詢也稱折半查詢,它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。 二分查詢想必大家都不陌生,很多程式的實現都會用到這種演算法,在這裡是想改正自己之前對二分查詢的一些不正確的理解。 請看下面的

常見排序演算法的C++描述

首先看一下幾種常見排序的特性 插入排序 void insertSort(vector<int> & arr) { int sz = arr.size();

字串--java面試題, 首重複字串,二分查詢

對於一個字串,請設計一個高效演算法,找到第一次重複出現的字元。 給定一個字串(不一定全為字母)A及它的長度n。請返回第一個重複出現的字元。保證字串中有重複字元,字串的長度小於等於500。 測試樣例: "qywyer23tdd",11 返回:y public class FirstRepeat {