forked from huihut/interview
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
380 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#include<iterator> | ||
#include<iostream> | ||
#include<vector> | ||
using namespace std; | ||
|
||
/***************** | ||
桶排序序思路: | ||
1. 设置一个定量的数组当作空桶子。 | ||
2. 寻访序列,并且把项目一个一个放到对应的桶子去。 | ||
3. 对每个不是空的桶子进行排序。 | ||
4. 从不是空的桶子里把项目再放回原来的序列中。 | ||
假设数据分布在[0,100)之间,每个桶内部用链表表示,在数据入桶的同时插入排序,然后把各个桶中的数据合并。 | ||
*****************/ | ||
|
||
|
||
const int BUCKET_NUM = 10; | ||
|
||
struct ListNode{ | ||
explicit ListNode(int i=0):mData(i),mNext(NULL){} | ||
ListNode* mNext; | ||
int mData; | ||
}; | ||
|
||
ListNode* insert(ListNode* head,int val){ | ||
ListNode dummyNode; | ||
ListNode *newNode = new ListNode(val); | ||
ListNode *pre,*curr; | ||
dummyNode.mNext = head; | ||
pre = &dummyNode; | ||
curr = head; | ||
while(NULL!=curr && curr->mData<=val){ | ||
pre = curr; | ||
curr = curr->mNext; | ||
} | ||
newNode->mNext = curr; | ||
pre->mNext = newNode; | ||
return dummyNode.mNext; | ||
} | ||
|
||
|
||
ListNode* Merge(ListNode *head1,ListNode *head2){ | ||
ListNode dummyNode; | ||
ListNode *dummy = &dummyNode; | ||
while(NULL!=head1 && NULL!=head2){ | ||
if(head1->mData <= head2->mData){ | ||
dummy->mNext = head1; | ||
head1 = head1->mNext; | ||
}else{ | ||
dummy->mNext = head2; | ||
head2 = head2->mNext; | ||
} | ||
dummy = dummy->mNext; | ||
} | ||
if(NULL!=head1) dummy->mNext = head1; | ||
if(NULL!=head2) dummy->mNext = head2; | ||
|
||
return dummyNode.mNext; | ||
} | ||
|
||
void BucketSort(int n,int arr[]){ | ||
vector<ListNode*> buckets(BUCKET_NUM,(ListNode*)(0)); | ||
for(int i=0;i<n;++i){ | ||
int index = arr[i]/BUCKET_NUM; | ||
ListNode *head = buckets.at(index); | ||
buckets.at(index) = insert(head,arr[i]); | ||
} | ||
ListNode *head = buckets.at(0); | ||
for(int i=1;i<BUCKET_NUM;++i){ | ||
head = Merge(head,buckets.at(i)); | ||
} | ||
for(int i=0;i<n;++i){ | ||
arr[i] = head->mData; | ||
head = head->mNext; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/***************** | ||
计数排序基于一个假设,待排序数列的所有数均出现在(0,k)的区间之内,如果k过大则会引起较大的空间复杂度 | ||
计数排序并非是一种基于比较的排序方法,它直接统计出键值本应该出现的位置 | ||
时间复杂度为O(n),空间复杂度为O(n+k) | ||
*****************/ | ||
|
||
|
||
#include<iostream> | ||
#include<vector> | ||
|
||
using namespace std; | ||
|
||
void countSort(vector<int>& vec,vector<int>& objVec) | ||
{ | ||
vector<int> range(10,0); //range的下标即键值 | ||
for(int i=0;i<vec.size();++i) | ||
{//统计每个键值出现的次数 | ||
range[vec[i]]++; | ||
} | ||
|
||
for(int i=1;i<vec.size();++i) | ||
{//后面的键值出现的位置为前面所有键值出现的次数之和 | ||
range[i]+=range[i-1]; | ||
} | ||
//至此,range中存放的是相应键值应该出现的位置 | ||
int length=vec.size(); | ||
for(int i=length-1;i>=0;--i) //注意一个小细节,统计时最正序的,这里是逆序 | ||
{//如果存在相同的键值,为了保持稳定性,后出现的应该还是位于后面 | ||
//如果正序,则先出现的会放置到后面,因此不再稳定 | ||
objVec[range[vec[i]]]=vec[i]; //将键值放到目标位置 | ||
range[vec[i]]--; | ||
} | ||
} | ||
|
||
int main() | ||
{ | ||
int a[14]={0,5,7,9,6,3,4,5,2,8,6,9,2,1}; | ||
vector<int> vec(a,a+14); | ||
vector<int> objVec(14,0); | ||
|
||
countSort(vec,objVec); | ||
|
||
for(int i=0;i<objVec.size();++i) | ||
cout<<objVec[i]<<" "; | ||
cout<<endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <iostream> | ||
#include <algorithm> | ||
using namespace std; | ||
|
||
void max_heapify(int arr[], int start, int end) { | ||
//建立父節點指標和子節點指標 | ||
int dad = start; | ||
int son = dad * 2 + 1; | ||
while (son <= end) { //若子節點指標在範圍內才做比較 | ||
if (son + 1 <= end && arr[son] < arr[son + 1]) //先比較兩個子節點大小,選擇最大的 | ||
son++; | ||
if (arr[dad] > arr[son]) //如果父節點大於子節點代表調整完畢,直接跳出函數 | ||
return; | ||
else { //否則交換父子內容再繼續子節點和孫節點比較 | ||
swap(arr[dad], arr[son]); | ||
dad = son; | ||
son = dad * 2 + 1; | ||
} | ||
} | ||
} | ||
|
||
void heap_sort(int arr[], int len) { | ||
//初始化,i從最後一個父節點開始調整 | ||
for (int i = len / 2 - 1; i >= 0; i--) | ||
max_heapify(arr, i, len - 1); | ||
//先將第一個元素和已经排好的元素前一位做交換,再從新調整(刚调整的元素之前的元素),直到排序完畢 | ||
for (int i = len - 1; i > 0; i--) { | ||
swap(arr[0], arr[i]); | ||
max_heapify(arr, 0, i - 1); | ||
} | ||
} | ||
|
||
int main() { | ||
int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 }; | ||
int len = (int) sizeof(arr) / sizeof(*arr); | ||
heap_sort(arr, len); | ||
for (int i = 0; i < len; i++) | ||
cout << arr[i] << ' '; | ||
cout << endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
插入排序思路: | ||
1. 从第一个元素开始,该元素可以认为已经被排序 | ||
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描 | ||
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置 | ||
4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 | ||
5. 将新元素插入到该位置后 | ||
6. 重复步骤2~5 | ||
*/ | ||
|
||
// 插入排序 | ||
void InsertSort(vector<int>& v) | ||
{ | ||
int len = v.size(); | ||
for (int i = 1; i < len - 1; ++i) { | ||
int temp = v[i]; | ||
for(int j = i - 1; j >= 0; --j) | ||
{ | ||
if(v[j] > temp) | ||
{ | ||
v[j + 1] = v[j]; | ||
v[j] = temp; | ||
} | ||
else | ||
break; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/***************** | ||
迭代版 | ||
*****************/ | ||
//整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)的運算子功能 | ||
template<typename T> | ||
void merge_sort(T arr[], int len) { | ||
T* a = arr; | ||
T* b = new T[len]; | ||
for (int seg = 1; seg < len; seg += seg) { | ||
for (int start = 0; start < len; start += seg + seg) { | ||
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len); | ||
int k = low; | ||
int start1 = low, end1 = mid; | ||
int start2 = mid, end2 = high; | ||
while (start1 < end1 && start2 < end2) | ||
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++]; | ||
while (start1 < end1) | ||
b[k++] = a[start1++]; | ||
while (start2 < end2) | ||
b[k++] = a[start2++]; | ||
} | ||
T* temp = a; | ||
a = b; | ||
b = temp; | ||
} | ||
if (a != arr) { | ||
for (int i = 0; i < len; i++) | ||
b[i] = a[i]; | ||
b = a; | ||
} | ||
delete[] b; | ||
} | ||
|
||
/***************** | ||
递归版 | ||
*****************/ | ||
template<typename T> | ||
void merge_sort_recursive(T arr[], T reg[], int start, int end) { | ||
if (start >= end) | ||
return; | ||
int len = end - start, mid = (len >> 1) + start; | ||
int start1 = start, end1 = mid; | ||
int start2 = mid + 1, end2 = end; | ||
merge_sort_recursive(arr, reg, start1, end1); | ||
merge_sort_recursive(arr, reg, start2, end2); | ||
int k = start; | ||
while (start1 <= end1 && start2 <= end2) | ||
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++]; | ||
while (start1 <= end1) | ||
reg[k++] = arr[start1++]; | ||
while (start2 <= end2) | ||
reg[k++] = arr[start2++]; | ||
for (k = start; k <= end; k++) | ||
arr[k] = reg[k]; | ||
} | ||
//整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)的運算子功能 | ||
template<typename T> | ||
void merge_sort(T arr[], const int len) { | ||
T *reg = new T[len]; | ||
merge_sort_recursive(arr, reg, 0, len - 1); | ||
delete[] reg; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/***************** | ||
基数排序 | ||
*****************/ | ||
|
||
int maxbit(int data[], int n) //辅助函数,求数据的最大位数 | ||
{ | ||
int maxData = data[0]; ///< 最大数 | ||
/// 先求出最大数,再求其位数,这样有原先依次每个数判断其位数,稍微优化点。 | ||
for (int i = 1; i < n; ++i) | ||
{ | ||
if (maxData < data[i]) | ||
maxData = data[i]; | ||
} | ||
int d = 1; | ||
int p = 10; | ||
while (maxData >= p) | ||
{ | ||
//p *= 10; // Maybe overflow | ||
maxData /= 10; | ||
++d; | ||
} | ||
return d; | ||
/* int d = 1; //保存最大的位数 | ||
int p = 10; | ||
for(int i = 0; i < n; ++i) | ||
{ | ||
while(data[i] >= p) | ||
{ | ||
p *= 10; | ||
++d; | ||
} | ||
} | ||
return d;*/ | ||
} | ||
void radixsort(int data[], int n) //基数排序 | ||
{ | ||
int d = maxbit(data, n); | ||
int *tmp = new int[n]; | ||
int *count = new int[10]; //计数器 | ||
int i, j, k; | ||
int radix = 1; | ||
for(i = 1; i <= d; i++) //进行d次排序 | ||
{ | ||
for(j = 0; j < 10; j++) | ||
count[j] = 0; //每次分配前清空计数器 | ||
for(j = 0; j < n; j++) | ||
{ | ||
k = (data[j] / radix) % 10; //统计每个桶中的记录数 | ||
count[k]++; | ||
} | ||
for(j = 1; j < 10; j++) | ||
count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶 | ||
for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中 | ||
{ | ||
k = (data[j] / radix) % 10; | ||
tmp[count[k] - 1] = data[j]; | ||
count[k]--; | ||
} | ||
for(j = 0; j < n; j++) //将临时数组的内容复制到data中 | ||
data[j] = tmp[j]; | ||
radix = radix * 10; | ||
} | ||
delete []tmp; | ||
delete []count; | ||
} |
Oops, something went wrong.