本文根据胡凡 曾磊主编的算法笔记 整理的个人笔记:
本文对应算法笔记的第四章,阅读着可以自行对照课本
排序
#include <iostream>
#include <stdio.h>
using namespace std;
int arr[5];
void selectsort(int arr[],int len)//选择排序
{
for(int i=0;i<len;i++)//遍历数组中的每一个数值
{
int k=i;
for(int j=i;j<len;j++)//然后用这个数值后的数和他做比较,选出最小的一个数
{
if(arr[k]>arr[j])
k=j;
}
int temp=arr[i];//找到之后和他进行交换
arr[i]=arr[k];
arr[k]=temp;
}
}
int main()
{
for(int i=0;i<5;i++)
cin>>arr[i];
selectsort(arr,5);
for(int i=0;i<5;i++)
cout<<arr[i]<<" ";
cout<<endl;
return 0;
}
//插入排序
//这个比较简单,从一组数据中找到合适的位置插入
#include <iostream>
#include <stdio.h>
int arr[5]={2,3,4,5};//已经是有序,待插入的数为1
using namespace std;
void selectsort(int arr[],int len)//选择排序
{
for(int i=0;i<len;i++)//遍历数组中的每一个数值
{
int k=i;
for(int j=i;j<len;j++)//然后用这个数值后的数和他做比较,选出最小的一个数
{
if(arr[k]>arr[j])
k=j;
}
int temp=arr[i];//找到之后和他进行交换
arr[i]=arr[k];
arr[k]=temp;
}
}
void insertsort(int arr[],int num,int len)
{
arr[4]=num;
selectsort(arr,len);
}
int main()
{
insertsort(arr,1,5);
for(int i=0;i<5;i++)
cout<<arr[i]<<" ";
return 0;
}
【PAT A1025】PAT Ranking
https://pintia.cn/problem-sets/994805342720868352/problems/994805474338127872
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
struct student
{
char id[15];//准考证号
int score;
int location_number;//考场号
int location_rank;//考场内排名
}stu[30010];
bool cmp(student a,student b)
{
if(a.score!=b.score)//如果分数不相同就按分数的从高到低排序
return a.score > b.score;
else//否则按准考证号从小到大排序
return strcmp(a.id,b.id)<0;
}
int main()
{
int n,k,num=0;
scanf("%d",&n);
for(int i=0;i<n;i++)//考场数
{
scanf("%d",&k);
for(int j=0;j<k;j++)//每个考场内的考生人数
{
//然后开始输入信息,其实归根结底,我们是在用一张表
cin>>stu[num].id>>stu[num].score;
stu[num].location_number=i+1;//考场号赋值
num++;
}
sort(stu+num-k,stu+num,cmp);//将该考场的考生排序
stu[num-k].location_rank=1;
for(int j=num-k+1;j<num;j++)//对该考场剩余的考生
{
if(stu[j].score==stu[j-1].score)
{
//同一考场中分数相同,排名也相同
stu[j].location_rank=stu[j-1].location_rank;
}
else
{
//local_rank为该考生前的人数
stu[j].location_rank=j+1-(num-k);
}
}
}
printf("%d\n",num);//输出总考生数
sort(stu,stu+num,cmp);//将所有考生排序
int r=1;
for(int i=0;i<num;i++)
{
if(i>0&&stu[i].score!=stu[i-1].score)
{
r=i+1;//当前考生与上一个考生分数不同时,让r更新为人数+1;
}
printf("%s ",stu[i].id);
printf("%d %d %d\n",r,stu[i].location_number,stu[i].location_rank);
}
return 0;
}
散列
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
列题:
给出N个整数再给出M个整数判断后者是否出现过在前者中
简单的说如果运用散列的思想,我们可以采取空间换时间的想法来解决这个问题
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 100005
int hashtable[maxn]={false};
int main()
{
int n,m;
cin>>n>>m;
int num;
for(int i=0;i<n;i++)
{
cin>>num;
hashtable[num]=true;
}
for(int i=0;i<m;i++)
{
cin>>num;
if(hashtable[num])
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
递归问题分析的核心
一个合法的递归定义包含两个部分:基础情况和递归部分。
分析一个递归问题就是列出递归定义表达式的过程。
上面那个电影院排数的问题表达式可以列为:
f(n)={1,f(n−1)+1,n= 1n>1
f(n)={1,n= 1f(n−1)+1,n>1
几个经典题目
斐波那契数列
斐波那契数列的排列是:0,1,1,2,3,5,8,13,21,34,55,89,144……依次类推下去,你会发现,它后一个数等于前面两个数的和。在这个数列中的数字,就被称为斐波那契数。
递归思想:一个数等于前两个数的和。(这并不是废话,这是执行思路)
首先分析数列的递归表达式:
f(n)={n,f(n−1)+f(n−2),n<= 1n>1
long F(int n){
if (n<=1) return n;
return F(n-1)+F(n-2);
}
long F1(int n){
if (n<=1) return n;
long fn = 0;
long fn_1 = 1;
long fn_2 = 0;
for (int i = 2; i <= n; i++) {
fn = fn_1 + fn_2;
fn_2 = fn_1;
fn_1 = fn;
}
return fn;
}
贪心算法:
这部分内容被我写在另一份博客中:
地址