写在前面:最近准备刷一遍数据结构与算法这门课程,一来练习练习C++,二来系统的学习算法。在这里进行一些简单算法原理及实现的记录
1.冒泡排序
目的是将杂乱无章的一串数字从小到大排列。方法是每次对比相邻两个数,大的右移,每次循环可以找到一个最大的数放在最右边。
#include <iostream>
using namespace std;
void Bubble(int list[], int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n-i-1; j++) //注意这里不用循环n-1次
{
if (list[j] > list[j + 1])
std::swap(list[j], list[j + 1]);
}
}
}
int main()
{
int list[] = { 5,4,5,6,9,8,3,4,5 }, n = 9;
Bubble(list, n);
for (int k = 0; k < n; k++)
cout << list[k] << " ";
cout << endl;
return 0;
}
2.选择排序(优于冒泡法)
这种方法是不断寻找最小的数并将最小的数放在最左边。
void choose(int list[], int n)
{
for (int i = 0; i < n-1; i++)
{
int min=i;
for (int j = i + 1; j < n; j++)
if (list[j] <list[min])
min=j;
swap(list[i],list[min]);
}
}
3.二分查找
只适合于有序数列的查找,无序数列只能用顺序查找。
int BinarySearch(int *a, const int x, const int n)
{
int low, high, mid;
low = 0, high = n - 1;
while (low < high)
{
mid = (low + high) / 2;
if (x == a[mid])
return mid;
else if (x < a[mid])
high = mid-1;
else if (x > a[mid])
low = mid+1;
}
return -1;
}
4.递归
递归得到一串字符的所有排列组合
#include <iostream>
using namespace std;
void permulation(char *a, const int k, const int m);
int main()
{
char a[] = "abcd";
permulation(a, 0, 3);
return 0;
}
void permulation(char *a, const int k, const int m)
{
if (k == m)
{
for (int j = 0; j <= m; j++)
cout << a[j];
cout << endl;
}
else
{
for (int i = k; i <= m; i++)
{
swap(a[i], a[k]);
permulation(a, k + 1, m);
swap(a[i], a[k]);
}
}
}
5.插入排序
类似于排队,从后往前比,高的后移,直到遇到矮的就插到他的前面。
template<class T>
void InsertionSort(T *a, const int n)
{
int in, out;
for (out = 1; out < n; out++)
{
T temp = a[out];
in = out;
while (temp < a[in - 1] && in > 0)
{
a[in] = a[in - 1];
--in;
}
a[in] = temp;
}
}
6.快速排序
选择支点,将大于支点的数放在右边,小于支点的数放在左边,然后再分别对左边和右边的数列进行递归操作。
template<class T>
void QuickSort(T *a, const int left,const int right)
{
if (left < right)
{
int i = left, j = right;
T pivot = a[left];
while (true)
{
do i++; while (a[i] < pivot);
do j--; while (a[j] > pivot);
if (i > j) break;
swap(a[i], a[j]);
}
swap(a[left], a[j]);
QuickSort(a, left, j - 1);
QuickSort(a, j + 1, right);
}
}
int main()
{
int a[] = { 5,4,8,1,4,7,9,2,525,4,56,51 };
for (int i = 0; i < 12; i++) //需要12,11+1
{
cout << a[i] << " ";
}
cout << endl;
QuickSort(a, 0, 12);
for (int i = 0; i < 12; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
6.归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。先将序列划分成很多个小的序列,对每个小序列进行排序,再将已有序的子序列进行合并。
设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
//合并
template <class T>
void merge(T *data, T *result, int start, int end)
{
int leftlenth = (end-start+1)/2+1;
int leftindex = start;
int rightindex = start + leftlenth;
int i=start;
while(leftindex < start + leftlenth && rightindex<=end)
{
if(data[leftindex]>=data[rightindex])
result[i++] = data[rightindex++];
else
result[i++] = data[leftindex++];
}
while(leftindex < start + leftlenth)
result[i++]=data[leftindex++];
while(rightindex<=end)
result[i++] = data[rightindex++];
}
//划分排序
template <class T>
void mergeSort(T *data, T *result, int start, int end)
{
if(end - start == 1)
{
if(data[end]<data[start])
swap(data[end], data[start]);
return;
}
else if(end == start)
return;
else
{
mergeSort(data, result, start, (start+end+1)/2);
mergeSort(data, result, (start+end+1)/2+1, end);
merge(data, result, start, end);
for(int i=start;i<=end;i++)
data[i]=result[i];
}
}