既然自己选择了学习算法,便会一直坚持下去,完成自己既定的目标!
这一周下来,按照自己既定的计划,自己利用课余时间看深入浅出这本书。从第八章的初涉算法一直看到了第十七章的集合,自己对这部分的内容也有了一定的了解,以下是自己做的一些总结。
模拟与高精度,主要的还是高精度部分的内容。如果需要存储或者使用更大的整数,就可以用数组来模拟非常长的整数,观察数的特点,从而进行模拟进位。排序部分主要讲了计数排序,选择排序,冒泡排序,插入排序,快速排序。自己不熟悉的是插入排序,将无序区的数字从有序区的末尾开始往前比较,如果发现比自己小的数,就把有序区的正在比较的牌往后移一格,继续比较,直到待插牌遇到不大于自己的牌或者成为第一个为止。比赛常用的是快速排序,不断选择基准数字,将比基准数字小的放在左边,把比基准数字大的放在右边,直到将序列分为两组,左边序列都不大于基准数字,右边序列都不小于基准数字,就可以分别对左边和右边进行排序了。暴力枚举就是枚举出所有的情况,然后判断或者统计,从而解决问题,可以切换方法获取最佳的枚举方式。递推与递归就是将一个很大的任务分解成规模小的一些子任务,子任务分成更小的子任务,直到遇到初始条件,最后整理归纳解决大任务的思想就是递推与递归思想。贪心首先要证明贪心策略是正确的,才能考虑用贪心算法解决问题。证明贪心可以用假设法,数学归纳法,大胆的去猜测证明。二分查找就是不断的分成两半,缩小区间范围,从而找到需要找的数字。回溯算法,可以跳过一些无效状态,降低问题规模,节约程序运行时间。同样是寻找目标解,深度优先搜索寻找操作步骤字典序最小的解,而广度优先搜索可以找到步骤最小的解。线性表,一个线性表由多个具有相同类型的数据串在一起,每个元素有前驱后继。判断一个过程能否用栈来模拟,看是否满足后进先出或者先进后出。如果数据有先进先出的性质,可以考虑用队列,队列常使用在各类广度优先搜索算法上。二叉树,就类似于树的枝,干,叶,是一种非常重要的数据结构。集合部分,就是将一些元素单纯的聚集在一起,处理不相交可合并集合关系的数据结构叫做并查集。
以上就是对这部分内容的一个基本的概括,接下来自己将进一步精读,深入理解每个算法的含义,内化为自己的本领。
这一周过的挺充实忙碌的,但也暴露出了自己的一些问题,因为自己刚接触算法,不大懂,就会很容易出现一些厌烦的情绪,看不懂一个算法就那么一点点反感,好在自己也坚持去看了。接下来的一周里,我要更沉心静气,认真去思考每个算法,做到自己能够把代码打出来,不断提高自己的水平,克服自己的懒惰心理,争取取得巨大的进步。
以下给出插入排序和快速排序的算法:
一.插入排序
int A[maxn], n; //n为元素个数,数组下标为1到n
void insertSort() {
for (int i = 2; i <= n; i++) { //进行n-1趟排序
int temp = A[i], j = i; //temp临时存放A[i],j从i开始往前枚举
while (j > 1 && temp < A[j - 1]) { //只要temp小于前一个元素A[j-1]
A[j] = A[j - 1]; //把A[j-1]后移一位至A[j]
j--;
}
A[j] = temp; //插入位置为j
}
}
二.快速排序
#include
using namespace std;
int main()
{
void quickSort(int arr[], int left, int right);
int arr[] = { -1,23,56,43,-65,98,29 };
int length = sizeof(arr) / sizeof(arr[0]);
cout << "快速排序前: " << endl;
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
}
cout << endl;
quickSort(arr, 0, length - 1);
cout << "快速排序后: " << endl;
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
void quickSort(int arr[], int left, int right)
{
int l = left;//左下标
int r = right;//右下标
int pivot = arr[(left + right) / 2];//中轴值
//while循环的目的是让比pivot值小的放到左边,比pivot值大的放到右边
while (l < r)
{
//在pivot的左边一直找,找到大于等于pivot的值,才退出
while (arr[l] < pivot)
{
l++;
}
//在pivot的右边一直找,找到小于等于pivot的值,才退出
while (arr[r] > pivot)
{
r--;
}
//如果l>=r说明pivot的左右两边的值,已经按照左边全部是小于等于pivot的值,
//右边全部都是大于等于pivot的值
if (l >= r)
{
break;
}
//交换
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l]==pivot相等,r--,前移一步
if (arr[l] == pivot)
{
r--;
}
//如果交换完后,发现这个arr[r]==pivot相等,l++,后移一步
if (arr[r] == pivot)
{
l++;
}
}
//如果l==r,必须l++,r--,否则出现栈溢出
if (l == r)
{
l++;
r--;
}
//向左递归
if (left < r)
{
quickSort(arr, left, r);
}
//向右递归
if (right > l)
{
quickSort(arr, l, right);
}
}