Initial commit
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
46
上课Demo/1.计时实例.c
Normal file
46
上课Demo/1.计时实例.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include<stdio.h>
|
||||
#include<time.h>
|
||||
#include<math.h>
|
||||
clock_t start,end;
|
||||
/* clock_t 是 clock()函数返回的变量类型*/
|
||||
double duration;
|
||||
/* 被测函数运行时间,以秒为单位*/
|
||||
#define MAXN 101 /* 多项式最大项数,即多项式次数+1*/
|
||||
#define MAXK 1e5 /* 被测函数最大重复调用次数*/
|
||||
double f1(int n,double a[],double x);
|
||||
double f2(int n,double a[],double x);
|
||||
void run(double(*f)(int n,double *,double ),double a[],int func_n);
|
||||
int main(){
|
||||
int i;
|
||||
double a[MAXN]; /* 存储多项式的系数 */
|
||||
a[0]=1;
|
||||
for(i=1;i<MAXN;i++)
|
||||
a[i]=(double)(1.0/i);
|
||||
run(f1,a,1);
|
||||
run(f2,a,2);
|
||||
return 0;
|
||||
}
|
||||
double f1(int n,double a[],double x){
|
||||
int i;
|
||||
double p=a[0];
|
||||
for(i=1;i<n;i++)
|
||||
p+=(a[i]*pow(x,i));
|
||||
return p;
|
||||
}
|
||||
double f2(int n,double a[],double x){
|
||||
int i;
|
||||
double p=a[0];
|
||||
for(i=n;i>0;i--)
|
||||
p=a[i-1]+x*p;
|
||||
return p;
|
||||
}
|
||||
void run(double(*f)(int n,double *,double ),double a[],int func_n){
|
||||
int i;
|
||||
start = clock();
|
||||
for(i=0;i<MAXK;i++)
|
||||
f(MAXN-1,a,1.1);
|
||||
end = clock();
|
||||
duration = ((double)(end-start))/CLK_TCK;
|
||||
printf("ticks%d=%f\n",func_n,(double)(end-start));
|
||||
printf("duration%d=%6.2e\n",func_n,duration);
|
||||
}
|
||||
BIN
上课Demo/1.计时实例.exe
Normal file
BIN
上课Demo/1.计时实例.exe
Normal file
Binary file not shown.
150
上课Demo/10.堆的操作.cpp
Normal file
150
上课Demo/10.堆的操作.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
#define MaxData 100000
|
||||
#define ERROR -1
|
||||
typedef int ElementType;
|
||||
typedef struct HeapStruct *MaxHeap;
|
||||
struct HeapStruct{
|
||||
ElementType *Elements; // 存储堆元素的数组
|
||||
int Size; // 堆的当前元素个数
|
||||
int Capacity; // 堆的最大容量
|
||||
};
|
||||
|
||||
MaxHeap Create(int MaxSize); // 建堆
|
||||
bool IsFull(MaxHeap H); // 判断堆是否满
|
||||
bool Insert(MaxHeap H,ElementType item); // 插入元素
|
||||
bool IsEmpty(MaxHeap H); // 判断堆是否为空
|
||||
ElementType DeleteMax(MaxHeap H); // 删除并返回堆中最大元素
|
||||
void LevelOrderTraversal(MaxHeap H); // 层序遍历
|
||||
|
||||
// 建堆
|
||||
MaxHeap Create(int MaxSize){
|
||||
MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapStruct));
|
||||
// Elements[0] 作为哨兵,堆元素从 Elements[1] 开始存放
|
||||
H->Elements = (ElementType *)malloc((MaxSize+1) * sizeof(ElementType));
|
||||
H->Size = 0;
|
||||
H->Capacity = MaxSize;
|
||||
// "哨兵"大于堆中所有可能的值
|
||||
H->Elements[0] = MaxData;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 插入,从完全二叉树的最后一个位置插入
|
||||
bool Insert(MaxHeap H,ElementType item){
|
||||
if(IsFull(H)){
|
||||
printf("堆已满,无法插入!\n");
|
||||
return false;
|
||||
}
|
||||
int i = ++H->Size; // 指向堆中最后一个位置
|
||||
for(;H->Elements[i/2] < item;i/=2) // 向上找比 item 大的结点
|
||||
H->Elements[i] = H->Elements[i/2]; // 向下赋值
|
||||
H->Elements[i] = item; // 找到了,把 item 值放进去
|
||||
return true;
|
||||
}
|
||||
|
||||
// 删除,从根结点删除
|
||||
ElementType DeleteMax(MaxHeap H){
|
||||
int parent,child;
|
||||
ElementType Max,tmp;
|
||||
if(IsEmpty(H)){
|
||||
printf("堆为空,无法删除!\n");
|
||||
return ERROR;
|
||||
}
|
||||
Max = H->Elements[1]; // 拿到最大值
|
||||
tmp = H->Elements[H->Size--]; // 拿到完全二叉树最后一个值
|
||||
// 判别条件:parent 是否有左孩子结点
|
||||
for(parent=1;parent*2<=H->Size;parent=child){
|
||||
// 左右孩子结点中找较大的值
|
||||
child = 2 * parent; // 左孩子结点
|
||||
// child!=H->Size 表示 child 不为当前最后一个结点,即 parent 有右孩子结点
|
||||
if((child!=H->Size) &&(H->Elements[child] < H->Elements[child+1]))
|
||||
child++;
|
||||
// 给 tmp 找个合适的位置
|
||||
// 如果当前左右孩子结点比 tmp 都小,说明 tmp 位置已经合适
|
||||
if(H->Elements[child] <= tmp)
|
||||
break;
|
||||
else // 否则把较大的孩子结点提上来,自己继续下去找
|
||||
H->Elements[parent] = H->Elements[child];
|
||||
}
|
||||
H->Elements[parent] = tmp; // 在合适的位置把 tmp 放进去
|
||||
return Max;
|
||||
}
|
||||
|
||||
// 判断是否已经满
|
||||
bool IsFull(MaxHeap H){
|
||||
return (H->Size == H->Capacity);
|
||||
}
|
||||
|
||||
// 判断是否为空
|
||||
bool IsEmpty(MaxHeap H){
|
||||
return !H->Size;
|
||||
}
|
||||
|
||||
// 层序遍历
|
||||
void LevelOrderTraversal(MaxHeap H){
|
||||
int i;
|
||||
printf("层序遍历的结果是:");
|
||||
for(i = 1;i<=H->Size;i++){
|
||||
printf("%d ",H->Elements[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(){
|
||||
MaxHeap H;
|
||||
int MaxSize = 100;
|
||||
H = Create(MaxSize);
|
||||
Insert(H,55);
|
||||
Insert(H,66);
|
||||
Insert(H,44);
|
||||
Insert(H,33);
|
||||
Insert(H,11);
|
||||
Insert(H,22);
|
||||
Insert(H,88);
|
||||
Insert(H,99);
|
||||
/*
|
||||
99
|
||||
/ \
|
||||
88 66
|
||||
/ \ / \
|
||||
55 11 22 44
|
||||
/
|
||||
33
|
||||
*/
|
||||
LevelOrderTraversal(H);
|
||||
DeleteMax(H);
|
||||
LevelOrderTraversal(H);
|
||||
DeleteMax(H);
|
||||
LevelOrderTraversal(H);
|
||||
DeleteMax(H);
|
||||
LevelOrderTraversal(H);
|
||||
DeleteMax(H);
|
||||
LevelOrderTraversal(H);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/10.堆的操作.exe
Normal file
BIN
上课Demo/10.堆的操作.exe
Normal file
Binary file not shown.
120
上课Demo/11.堆的两种建立方式.cpp
Normal file
120
上课Demo/11.堆的两种建立方式.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
const int MinData = -100000; // 哨兵值
|
||||
const int MaxSize = 1005; // 最大个数
|
||||
using namespace std;
|
||||
typedef struct HeapStruct *Heap;
|
||||
struct HeapStruct{
|
||||
int *data; // 存值的数组
|
||||
int size; // 当前元素个数
|
||||
int capacity; // 最大容量
|
||||
};
|
||||
|
||||
// 初始化堆
|
||||
Heap Create(){
|
||||
Heap H;
|
||||
H = (Heap)malloc(sizeof(struct HeapStruct));
|
||||
H->data = (int *)malloc(sizeof(int) * (MaxSize+1));
|
||||
H->size = 0;
|
||||
H->capacity = MaxSize;
|
||||
H->data[0] = MinData;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 排序,类似堆的"删除操作"
|
||||
void sort(Heap H,int i){
|
||||
int child,parent;
|
||||
int tmp = H->data[i]; // 拿到当前"根结点的值"
|
||||
for(parent = i;parent*2<=H->size;parent = child){
|
||||
child = 2 * parent;
|
||||
if((child!=H->size) && (H->data[child+1] < H->data[child]))
|
||||
child++;
|
||||
if(H->data[child] >= tmp)
|
||||
break;
|
||||
else
|
||||
H->data[parent] = H->data[child];
|
||||
}
|
||||
H->data[parent] = tmp;
|
||||
}
|
||||
// 调整
|
||||
void adjust(Heap H){
|
||||
int i= H->size/2;
|
||||
for(;i>0;i--){
|
||||
// 以每个有孩子结点的结点作为根结点,对其子树进行堆排序
|
||||
sort(H,i);
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历
|
||||
void bl(Heap H){
|
||||
for(int i=1;i<=H->size;i++){
|
||||
cout<<H->data[i]<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
Heap H;
|
||||
H = Create();
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++)
|
||||
cin>>H->data[++H->size];
|
||||
adjust(H);
|
||||
bl(H);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
const int MinData = -100000; // 哨兵值
|
||||
const int MaxSize = 1005; // 最大个数
|
||||
using namespace std;
|
||||
typedef struct HeapStruct *Heap;
|
||||
struct HeapStruct{
|
||||
int *data; // 存值的数组
|
||||
int size; // 当前元素个数
|
||||
int capacity; // 最大容量
|
||||
};
|
||||
|
||||
// 初始化堆
|
||||
Heap Create(){
|
||||
Heap H;
|
||||
H = (Heap)malloc(sizeof(struct HeapStruct));
|
||||
H->data = (int *)malloc(sizeof(int) * (MaxSize+1));
|
||||
H->size = 0;
|
||||
H->capacity = MaxSize;
|
||||
H->data[0] = MinData;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 插入
|
||||
void Insert(Heap H,int x){
|
||||
int i = ++H->size; // 指向数组最后一个
|
||||
for(;H->data[i/2]>x;i/=2)
|
||||
H->data[i] = H->data[i/2];
|
||||
H->data[i] = x;
|
||||
}
|
||||
|
||||
// 遍历
|
||||
void bl(Heap H){
|
||||
for(int i=1;i<=H->size;i++)
|
||||
cout<<H->data[i];
|
||||
}
|
||||
|
||||
int main(){
|
||||
Heap H;
|
||||
H = Create();
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++){
|
||||
int t;
|
||||
cin>>t;
|
||||
Insert(H,t);
|
||||
}
|
||||
bl(H);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
BIN
上课Demo/11.堆的两种建立方式.exe
Normal file
BIN
上课Demo/11.堆的两种建立方式.exe
Normal file
Binary file not shown.
155
上课Demo/12.哈夫曼树.cpp
Normal file
155
上课Demo/12.哈夫曼树.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
#define MaxSize 1000
|
||||
#define MinData -1000
|
||||
int A[] = {13,1,45,7,20,4,19,13,40,33,38}; // 预先定义好一组权值
|
||||
int A_length = 11; // 定义其长度
|
||||
typedef struct HeapStruct *MinHeap;
|
||||
typedef struct TreeNode *HuffmanTree;
|
||||
struct HeapStruct{ // 存放哈夫曼树的堆
|
||||
HuffmanTree *data; // 存值的数组
|
||||
int size; // 堆的当前大小
|
||||
int capacity; // 最大容量
|
||||
};
|
||||
struct TreeNode{ // 哈夫曼树
|
||||
int weight; //权值
|
||||
HuffmanTree Left; // 左子树
|
||||
HuffmanTree right; // 右子树
|
||||
};
|
||||
using namespace std;
|
||||
|
||||
MinHeap create(); // 初始化堆
|
||||
HuffmanTree Create(); // 初始化哈夫曼树
|
||||
void sort(MinHeap H,int i); // 调整子最小堆
|
||||
void adjust(MinHeap H); // 调整最小堆
|
||||
void BuildMinHeap(MinHeap H); // 建堆
|
||||
HuffmanTree Delete(MinHeap H); // 删除最小堆元素
|
||||
void Insert(MinHeap H,HuffmanTree Huff); // 插入最小堆元素
|
||||
void PreOrderTraversal(HuffmanTree Huff); // 先序遍历
|
||||
HuffmanTree Huffman(MinHeap H); // 哈夫曼树的构建
|
||||
|
||||
// 初始化堆
|
||||
MinHeap create(){
|
||||
MinHeap H;
|
||||
HuffmanTree Huff;
|
||||
H = (MinHeap)malloc(sizeof(struct HeapStruct));
|
||||
H->data = (HuffmanTree *)malloc(sizeof(struct TreeNode) * (MaxSize+1));
|
||||
H->capacity = MaxSize;
|
||||
H->size = 0;
|
||||
// 给堆置哨兵
|
||||
Huff = Create();
|
||||
Huff->weight = MinData;
|
||||
H->data[0] = Huff;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 初始化哈夫曼树
|
||||
HuffmanTree Create(){
|
||||
HuffmanTree Huff;
|
||||
Huff = (HuffmanTree)malloc(sizeof(struct TreeNode));
|
||||
Huff->weight = 0;
|
||||
Huff->Left = NULL;
|
||||
Huff->right = NULL;
|
||||
return Huff;
|
||||
}
|
||||
|
||||
// 调整子最小堆
|
||||
void sort(MinHeap H,int i){
|
||||
int parent,child;
|
||||
int tmp = H->data[i]->weight; // 取出当前"根结点"值
|
||||
for(parent=i;parent*2<=H->size;parent = child){
|
||||
child = 2 * parent;
|
||||
if((child!=H->size) && (H->data[child+1]->weight < H->data[child]->weight))
|
||||
child++;
|
||||
if(H->data[child]->weight >= tmp)
|
||||
break;
|
||||
else
|
||||
H->data[parent] = H->data[child];
|
||||
}
|
||||
H->data[parent]->weight = tmp;
|
||||
}
|
||||
|
||||
// 调整最小堆
|
||||
void adjust(MinHeap H){
|
||||
for(int i =H->size/2;i>0;i--)
|
||||
sort(H,i);// 每个"子最小堆"调整
|
||||
}
|
||||
|
||||
// 建堆
|
||||
void BuildMinHeap(MinHeap H){
|
||||
// 将权值读入堆中
|
||||
HuffmanTree Huff;
|
||||
for(int i=0;i<A_length;i++){
|
||||
Huff = Create();
|
||||
Huff->weight = A[i];
|
||||
H->data[++H->size] = Huff;
|
||||
}
|
||||
// 调整堆
|
||||
adjust(H);
|
||||
}
|
||||
|
||||
|
||||
// 删除最小堆元素
|
||||
HuffmanTree Delete(MinHeap H){
|
||||
int parent,child;
|
||||
HuffmanTree T = H->data[1]; // 取出根结点的哈夫曼树
|
||||
HuffmanTree tmp = H->data[H->size--]; // 取出最后一个结点哈夫曼树的权值
|
||||
for(parent=1;parent*2<=H->size;parent = child){
|
||||
child = 2 * parent;
|
||||
if((child!=H->size) && (H->data[child+1]->weight < H->data[child]->weight))
|
||||
child++;
|
||||
if(H->data[child]->weight >= tmp->weight)
|
||||
break;
|
||||
else
|
||||
H->data[parent] = H->data[child];
|
||||
}
|
||||
H->data[parent] = tmp;
|
||||
// 构造一个 HuffmanTree 结点,附上刚才取出来的权值,返回该结点
|
||||
return T;
|
||||
}
|
||||
|
||||
// 插入一个哈夫曼树
|
||||
void Insert(MinHeap H,HuffmanTree Huff){
|
||||
int weight = Huff->weight; // 取出权值
|
||||
int i = ++H->size;
|
||||
for(;H->data[i/2]->weight > weight;i/=2)
|
||||
H->data[i] = H->data[i/2];
|
||||
H->data[i] = Huff;
|
||||
}
|
||||
|
||||
//遍历
|
||||
void PreOrderTraversal(HuffmanTree Huff){
|
||||
if(Huff){
|
||||
cout<<Huff->weight<<" ";
|
||||
PreOrderTraversal(Huff->Left);
|
||||
PreOrderTraversal(Huff->right);
|
||||
}
|
||||
}
|
||||
|
||||
// 哈夫曼树的构造
|
||||
HuffmanTree Huffman(MinHeap H){
|
||||
HuffmanTree T;
|
||||
BuildMinHeap(H); // 建堆
|
||||
int times = H->size;
|
||||
// 做 times-1 次合并
|
||||
for(int i=1;i<times;i++){
|
||||
T = (HuffmanTree)malloc(sizeof(struct TreeNode));
|
||||
T->Left = Delete(H); // 从堆中删除一个结点,作为新 T 的左子结点
|
||||
T->right = Delete(H); // 从堆中删除一个结点,作为新 T 的右子结点
|
||||
T->weight = T->Left->weight + T->right->weight; // 重新计算权值
|
||||
Insert(H,T); // 再加进堆中
|
||||
}
|
||||
T = Delete(H);
|
||||
return T;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(){
|
||||
MinHeap H;
|
||||
HuffmanTree Huff;
|
||||
H = create();
|
||||
Huff = Huffman(H);
|
||||
PreOrderTraversal(Huff);
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/12.哈夫曼树.exe
Normal file
BIN
上课Demo/12.哈夫曼树.exe
Normal file
Binary file not shown.
50
上课Demo/13.并查集的表示.cpp
Normal file
50
上课Demo/13.并查集的表示.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#define MaxSize 1000
|
||||
typedef int ElementType;
|
||||
typedef struct{
|
||||
ElementType Data; // 存值
|
||||
int parent; // 指向父结点
|
||||
}SetType;
|
||||
using namespace std;
|
||||
|
||||
// 查找
|
||||
int Find(SetType s[],ElementType x){
|
||||
int i;
|
||||
// 找到数组中该值对应的下标
|
||||
for(i=0;i<MaxSize && s[i].Data!=x;i++);
|
||||
if(MaxSize <= i) // 如果没有找到,返回 -1
|
||||
return -1;
|
||||
// 找到该结点的根结点
|
||||
for(;s[i].parent >= 0;i = s[i].parent);
|
||||
return i; // 返回根结点在数组 s 中的下标
|
||||
}
|
||||
|
||||
// 并
|
||||
void Union(SetType s[],ElementType x1,ElementType x2){
|
||||
int root1 = Find(s,x1); // 找到 x1 的根结点下标
|
||||
int root2 = Find(s,x2); // 找到 x2 的根结点下标
|
||||
// 如果根结点的下标不同,说明不是一个集合
|
||||
if(root1 != root2){
|
||||
s[root1].parent = root2; // 把 x1 挂到 x2 的集合
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
SetType s[MaxSize];
|
||||
// 初始化数组,父结点全部指向 -1
|
||||
for(int i=0;i<MaxSize;i++){
|
||||
s[i].Data = i+1;
|
||||
s[i].parent = -1;
|
||||
}
|
||||
cout<<Find(s,5)<<endl;
|
||||
Union(s,3,5);
|
||||
cout<<Find(s,4)<<endl;
|
||||
cout<<Find(s,3)<<endl;
|
||||
Union(s,1,3);
|
||||
Union(s,2,4);
|
||||
Union(s,8,6);
|
||||
cout<<Find(s,6)<<endl;
|
||||
cout<<Find(s,8)<<endl;
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/13.并查集的表示.exe
Normal file
BIN
上课Demo/13.并查集的表示.exe
Normal file
Binary file not shown.
300
上课Demo/14.排序算法的实现.cpp
Normal file
300
上课Demo/14.排序算法的实现.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
#include<iostream>
|
||||
#include<cstdlib>
|
||||
#include<algorithm>
|
||||
#include<cmath>
|
||||
#define NumSize 20
|
||||
int A[NumSize];
|
||||
using namespace std;
|
||||
|
||||
// 生成随机数
|
||||
void Random(){
|
||||
for(int i=0;i<NumSize;i++)
|
||||
A[i] = rand()%NumSize+1;
|
||||
}
|
||||
|
||||
// 输出
|
||||
void output(){
|
||||
for(int i=0;i<NumSize;i++)
|
||||
cout<<A[i]<<" ";
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
// 冒泡排序
|
||||
void Bubble_sort(int N){
|
||||
for(int p = N-1;p>=0;p--){ // 总共 n-1 趟
|
||||
bool flag = false;
|
||||
for(int j=0;j<p;j++){ // 一趟排序
|
||||
if(A[j+1] < A[j]){
|
||||
swap(A[j],A[j+1]);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
if(!flag) // 如果全程无交换,可以此次排序了
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 插入排序
|
||||
void Insertion_sort(int A[],int N){
|
||||
for(int p = 1;p<N;p++){
|
||||
int tmp = A[p]; // 取出一个数
|
||||
int j = p;
|
||||
for(;tmp<A[j-1] && j > 0;j--) // 找到这个数适合的位置
|
||||
A[j] = A[j-1]; // “腾“出位置
|
||||
A[j] = tmp; // 把合适大小的数放入
|
||||
}
|
||||
}
|
||||
|
||||
// 原始希尔排序
|
||||
void shell_sort(int N){
|
||||
for(int D=N/2;D>0;D/=2){
|
||||
for(int p=D;p<N;p+=D){
|
||||
int tmp = A[p];
|
||||
int j = p;
|
||||
for(;j>=D && tmp<A[j-D] ;j-=D) // j>=D 在前,因为也许 A[j-D]已经越界
|
||||
A[j] = A[j-D];
|
||||
A[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hibbard增量序列希尔排序
|
||||
void Hibbard_shell_sort(int N){
|
||||
int add[]={32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0};
|
||||
int i=0;
|
||||
for(int D=add[i];D>0;D=add[++i]){
|
||||
for(int p=D;p<N;p++){
|
||||
long tmp = A[p];
|
||||
int k=p;
|
||||
for(;k>=D && tmp<A[k-D] ;k-=D) // j>=D 在前,因为也许 A[j-D]已经越界
|
||||
A[k] = A[k-D];
|
||||
A[k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sedgewick增量序列希尔排序
|
||||
void Sedgewick_shell_sort(int N){
|
||||
int add[]= {587521,260609,146305,64769,36289,16001,8929,3905,2161,929,505,209,109,41,19,5,1,0};
|
||||
int i=0;
|
||||
for(int D=add[i];D>0;D=add[++i]){
|
||||
for(int p=D;p<N;p++){
|
||||
long tmp = A[p];
|
||||
int k = p;
|
||||
for(;k>=D && tmp<A[k-D];k-=D)
|
||||
A[k] = A[k-D];
|
||||
A[k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************堆排序开始******************************/
|
||||
// 调整成最大堆
|
||||
void PrecDown(int i,int N){
|
||||
int child,parent;
|
||||
int tmp = A[i]; // 拿到当前"根"结点的值
|
||||
// 下标从 0 开始,注意结束范围和父子结点之间的关系
|
||||
for(parent = i;parent*2+1<=N-1;parent = child){
|
||||
child = 2*parent + 1;
|
||||
if((child!=N-1) && (A[child] < A[child+1])) // 选最大的
|
||||
child++;
|
||||
if(A[child] <= tmp)
|
||||
break;
|
||||
A[parent] = A[child];
|
||||
}
|
||||
A[parent] = tmp;
|
||||
}
|
||||
|
||||
void swap(int &a,int &b){
|
||||
int t =a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
|
||||
// 堆排序
|
||||
void Heap_sort(int N){
|
||||
// buildHeap
|
||||
for(int i=N/2;i>=0;i--)
|
||||
PrecDown(i,N);
|
||||
for(int i=N-1;i>0;i--){
|
||||
swap(A[0],A[i]);
|
||||
PrecDown(0,i);
|
||||
}
|
||||
}
|
||||
/*******************堆排序结束******************************/
|
||||
|
||||
|
||||
/********************归并排序(递归)开始******************************/
|
||||
// 归并排序实现
|
||||
void Merge(int A[],int tmpA[],int L,int R,int RightEnd){
|
||||
// L = 左边起始位置,R = 右边起始位置,RightEnd = 右边终点位置
|
||||
int LeftEnd = R-1; // 左边终点位置
|
||||
int tmp = L; // 存放结果的开始位置
|
||||
int NumElements = RightEnd - L + 1; // 归并个数
|
||||
while(L<=LeftEnd && R<=RightEnd){
|
||||
if(A[L] <= A[R])
|
||||
tmpA[tmp++] = A[L++];
|
||||
else
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
// 左边有剩
|
||||
while(L<=LeftEnd)
|
||||
tmpA[tmp++] = A[L++];
|
||||
// 右边有剩
|
||||
while(R<=RightEnd)
|
||||
tmpA[tmp++] = A[R++];
|
||||
// 导回结果
|
||||
for(int i=0;i<NumElements;i++,RightEnd--)
|
||||
A[RightEnd] = tmpA[RightEnd];
|
||||
}
|
||||
|
||||
// 分治
|
||||
void Msort(int A[],int tmpA[],int L,int RightEnd){
|
||||
// L = 左边起始位置,RightEnd = 右边终点位置
|
||||
// 如果还有元素
|
||||
if( L < RightEnd){
|
||||
int center = (L+RightEnd)/2;
|
||||
Msort(A,tmpA,L,center); // 左半边
|
||||
Msort(A,tmpA,center+1,RightEnd); // 右半边
|
||||
Merge(A,tmpA,L,center+1,RightEnd); // center+1 是右边起点
|
||||
}
|
||||
}
|
||||
/*
|
||||
// 归并排序(递归)
|
||||
void Merge_sort(int A[],int N){
|
||||
int tmpA[N];
|
||||
Msort(A,tmpA,0,N-1);
|
||||
}*/
|
||||
|
||||
/********************归并排序(递归)结束******************************/
|
||||
|
||||
/********************归并排序(非递归)结束******************************/
|
||||
|
||||
void Merge1(int A[],int tmpA[],int L,int R,int RightEnd){
|
||||
// L = 左边起始位置,R = 右边起始位置,RightEnd = 右边终点位置
|
||||
int LeftEnd = R-1; // 左边终点位置
|
||||
int tmp = L; // 存放结果的开始位置
|
||||
int NumElements = RightEnd - L + 1; // 归并个数
|
||||
while(L<=LeftEnd && R<=RightEnd){
|
||||
if(A[L] <= A[R])
|
||||
tmpA[tmp++] = A[L++];
|
||||
else
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
// 左边有剩
|
||||
while(L<=LeftEnd)
|
||||
tmpA[tmp++] = A[L++];
|
||||
// 右边有剩
|
||||
while(R<=RightEnd)
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
void Merge_pass(int A[],int tmpA[],int N,int length){
|
||||
// length = 当前有序子列长度
|
||||
int i;
|
||||
for(i=0;i<=N-2*length;i+=length*2)
|
||||
Merge1(A,tmpA,i,i+length,i+2*length-1);
|
||||
if(i+length<N)
|
||||
Merge1(A,tmpA,i,i+length,N-1);
|
||||
else
|
||||
for(int j=i;j<N;j++)
|
||||
tmpA[j] = A[j];
|
||||
}
|
||||
|
||||
void Merge_sort(int A[],int N){
|
||||
int length = 1;
|
||||
int tmpA[N];
|
||||
while(length<N){
|
||||
Merge_pass(A,tmpA,N,length);
|
||||
length *=2;
|
||||
Merge_pass(tmpA,A,N,length);
|
||||
length *=2;
|
||||
}
|
||||
}
|
||||
/********************归并排序(非递归)结束******************************/
|
||||
|
||||
/*********************快速排序开始*******************************************/
|
||||
|
||||
// 获得主元
|
||||
int GetPivot(int L,int R){
|
||||
int center = (L+R)/2;
|
||||
// 排序 A[L] < A[center] < A[R]
|
||||
if(A[R] < A[center])
|
||||
swap(A[R],A[center]);
|
||||
if(A[R] < A[L])
|
||||
swap(A[R],A[L]);
|
||||
if(A[center] < A[L])
|
||||
swap(A[L],A[center]);
|
||||
// 把主元藏在 R-1
|
||||
swap(A[center],A[R-1]);
|
||||
return A[R-1];
|
||||
}
|
||||
|
||||
// 快排实现
|
||||
void Quicksort(int Left,int Right){
|
||||
int cutoff = 100;
|
||||
if( cutoff <= Right-Left){
|
||||
int Pivot = GetPivot(Left,Right);
|
||||
int i = Left;
|
||||
int 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]);
|
||||
Quicksort(Left,i-1);
|
||||
Quicksort(i+1,Right);
|
||||
}else
|
||||
Insertion_sort(A+Left,Right-Left+1);
|
||||
}
|
||||
|
||||
void Quick_sort(int N){
|
||||
Quicksort(0,N-1);
|
||||
}
|
||||
/*********************快速排序结束************************/
|
||||
|
||||
/*********************桶排序开始********************/
|
||||
void Bucket_Sort(int N){
|
||||
int count[1000];
|
||||
// 范围多大桶就多少
|
||||
for(int i=0;i<1000;i++){
|
||||
count[i] = 0;
|
||||
}
|
||||
// 每个值倒入桶中
|
||||
for(int i=0;i<N;i++)
|
||||
count[A[i]]++;
|
||||
// 收集
|
||||
for(int i=0;i<N;i++)
|
||||
if(count[i]){
|
||||
for(int j=0;j<count[i];j++)
|
||||
cout<<i<<" ";
|
||||
}
|
||||
}
|
||||
|
||||
/*********************桶排序开始******************/
|
||||
|
||||
int main(){
|
||||
Random(); // 生成随机数
|
||||
output(); // 输出数组元素
|
||||
// Bubble_sort(NumSize); // 冒泡排序
|
||||
// Insertion_sort(NumSize); // 插入排序
|
||||
// shell_sort(NumSize); // 希尔排序
|
||||
// Heap_sort(NumSize); // 堆排序
|
||||
// Merge_sort(A,NumSize); // 归并排序
|
||||
// Hibbard_shell_sort(NumSize);
|
||||
// Sedgewick_shell_sort(NumSize);
|
||||
// Quick_sort(NumSize);
|
||||
Bucket_Sort(NumSize);
|
||||
// output();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/14.排序算法的实现.exe
Normal file
BIN
上课Demo/14.排序算法的实现.exe
Normal file
Binary file not shown.
105
上课Demo/15.图的邻接矩阵实现.c
Normal file
105
上课Demo/15.图的邻接矩阵实现.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define MaxVertexNum 100
|
||||
typedef int weightType;
|
||||
typedef int Vertex;
|
||||
typedef int DataType;
|
||||
typedef struct GNode *ptrToGNode;
|
||||
struct GNode{ // 图
|
||||
int Nv; // 顶点数
|
||||
int Ne; // 边数
|
||||
weightType G[MaxVertexNum][MaxVertexNum];
|
||||
DataType Data[MaxVertexNum]; // 存顶点的数据
|
||||
};
|
||||
typedef ptrToGNode MGraph;
|
||||
typedef struct ENode *ptrToENode;
|
||||
struct ENode{ // 边
|
||||
Vertex V1,V2; // 有向边<V1,V2>
|
||||
weightType Weight; // 权重
|
||||
};
|
||||
typedef ptrToENode Edge;
|
||||
|
||||
// 初始化图
|
||||
MGraph Create(int VertexNum){
|
||||
Vertex v,w;
|
||||
MGraph Graph;
|
||||
|
||||
Graph = (MGraph)malloc(sizeof(struct GNode));
|
||||
Graph->Nv = VertexNum;
|
||||
Graph->Ne = 0;
|
||||
|
||||
for(v=0;v<VertexNum;v++)
|
||||
for(w=0;w<VertexNum;w++)
|
||||
Graph->G[v][w] = 0;
|
||||
return Graph;
|
||||
}
|
||||
|
||||
// 插入边
|
||||
MGraph Insert(MGraph Graph,Edge E){
|
||||
|
||||
// 插入边 <V1,V2>
|
||||
Graph->G[E->V1][E->V2] = E->Weight;
|
||||
|
||||
// 如果是无向图,还需要插入边 <V2,V1>
|
||||
Graph->G[E->V2][E->V1] = E->Weight;
|
||||
|
||||
}
|
||||
|
||||
// 建图
|
||||
MGraph BuildGraph(){
|
||||
MGraph Graph;
|
||||
Edge E;
|
||||
Vertex V;
|
||||
int Nv,i;
|
||||
scanf("%d",&Nv); // 读入顶点数
|
||||
Graph = Create(Nv);
|
||||
scanf("%d",&(Graph->Ne)); // 读入边数
|
||||
if(Graph->Ne != 0){
|
||||
E = (Edge)malloc(sizeof(struct ENode));
|
||||
for(i=0;i<Graph->Ne;i++){
|
||||
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight); // 读入每个边的数据
|
||||
Insert(Graph,E);
|
||||
}
|
||||
}
|
||||
return Graph;
|
||||
}
|
||||
*/
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define MAXN 100
|
||||
int G[MAXN][MAXN],Nv,Ne;
|
||||
|
||||
void BuildGraph(){
|
||||
int i,j,v1,v2,w;
|
||||
|
||||
scanf("%d",&Nv);
|
||||
// 初始化图
|
||||
for(i=0;i<Nv;i++)
|
||||
for(j=0;j<Nv;j++)
|
||||
G[i][j] = 0;
|
||||
scanf("%d",&Ne);
|
||||
// 插入边
|
||||
for(i=0;i<Ne;i++){
|
||||
scanf("%d %d %d",&v1,&v2,&w);
|
||||
G[v1][v2] = w;
|
||||
G[v2][v1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 遍历图
|
||||
void print(){
|
||||
int i,j;
|
||||
for(i=0;i<Nv;i++){
|
||||
for(j=0;j<Nv;j++)
|
||||
printf("%d ",G[i][j]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
BuildGraph();
|
||||
print();
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/15.图的邻接矩阵实现.exe
Normal file
BIN
上课Demo/15.图的邻接矩阵实现.exe
Normal file
Binary file not shown.
176
上课Demo/16.图的邻接表实现.c
Normal file
176
上课Demo/16.图的邻接表实现.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define MaxVertexNum 100
|
||||
typedef int Vertex;
|
||||
typedef int DataType;
|
||||
typedef int weightType;
|
||||
|
||||
typedef struct ENode *ptrToENode;
|
||||
struct ENode{ // 边
|
||||
Vertex V1,V2; // 有向边<V1,V2>
|
||||
weightType Weight; // 权重
|
||||
};
|
||||
typedef ptrToENode Edge;
|
||||
|
||||
typedef struct AdjVNode *ptrToAdjVNode;
|
||||
struct AdjVNode{ // 邻接表内元素
|
||||
Vertex AdjV; // 邻接点下标
|
||||
weightType Weight; // 权值
|
||||
ptrToAdjVNode Next; // 下一个
|
||||
};
|
||||
|
||||
typedef struct VNode{ // 邻接表头
|
||||
ptrToAdjVNode FirstEdge; // 存每个顶点指针
|
||||
DataType Data; // 顶点数据
|
||||
}AdjList[MaxVertexNum];
|
||||
|
||||
typedef struct GNode *ptrToGNode;
|
||||
struct GNode{ // 图
|
||||
int Nv; // 顶点
|
||||
int Ne; // 边数
|
||||
AdjList G; // 邻接表
|
||||
};
|
||||
typedef ptrToGNode LGraph;
|
||||
|
||||
// 初始化
|
||||
LGraph create(int VertexNum){
|
||||
Vertex v,w;
|
||||
LGraph Graph;
|
||||
|
||||
Graph = (LGraph)malloc(sizeof(struct GNode));
|
||||
Graph->Nv = VertexNum; // 初始化边
|
||||
Graph->Ne = 0; // 初始化点
|
||||
|
||||
// 每条边的 FirstEdge 指向 NULL
|
||||
for(v=0;v<Graph->Nv;v++)
|
||||
Graph->G[v].FirstEdge = NULL;
|
||||
return Graph;
|
||||
}
|
||||
|
||||
|
||||
// 插入一条边到邻接表的顶点指针之后
|
||||
void InsertEdge(LGraph Graph,Edge E){
|
||||
ptrToAdjVNode newNode;
|
||||
|
||||
// 插入边<V1,V2>
|
||||
// 为 V2 建立新的结点
|
||||
newNode = (ptrToAdjVNode)malloc(sizeof(struct AdjVNode));
|
||||
newNode->AdjV = E->V2;
|
||||
newNode->Weight = E->Weight;
|
||||
|
||||
// 将 V2 插入到邻接表头
|
||||
newNode->Next = Graph->G[E->V1].FirstEdge;
|
||||
Graph->G[E->V1].FirstEdge = newNode;
|
||||
|
||||
// 若为无向图,插入边<V2,V1>
|
||||
newNode = (ptrToAdjVNode)malloc(sizeof(struct AdjVNode));
|
||||
newNode->AdjV = E->V1;
|
||||
newNode->Weight = E->Weight;
|
||||
|
||||
newNode->Next = Graph->G[E->V2].FirstEdge;
|
||||
Graph->G[E->V2].FirstEdge = newNode;
|
||||
}
|
||||
|
||||
// 建图
|
||||
LGraph BuildGraph(){
|
||||
LGraph Graph;
|
||||
Edge E;
|
||||
Vertex V;
|
||||
int Nv,i;
|
||||
scanf("%d",&Nv);
|
||||
Graph = create(Nv);
|
||||
scanf("%d",&(Graph->Ne));
|
||||
if(Graph->Ne != 0){
|
||||
for(i=0;i<Graph->Ne;i++){
|
||||
E = (Edge)malloc(sizeof(struct ENode));
|
||||
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
|
||||
InsertEdge(Graph,E);
|
||||
}
|
||||
}
|
||||
return Graph;
|
||||
}
|
||||
|
||||
// 打印
|
||||
void print(LGraph Graph){
|
||||
Vertex v;
|
||||
ptrToAdjVNode tmp;
|
||||
for(v=0;v<Graph->Nv;v++){
|
||||
tmp = Graph->G[v].FirstEdge;
|
||||
printf("%d ",v);
|
||||
while(tmp){
|
||||
printf("%d ",tmp->AdjV);
|
||||
tmp = tmp->Next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
LGraph Graph;
|
||||
Graph = BuildGraph();
|
||||
print(Graph);
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#define MaxVertexNum 100
|
||||
typedef struct AdjVNode *AdjList;
|
||||
struct AdjVNode{
|
||||
int weight; // 权值
|
||||
int adjv; // 下标
|
||||
AdjList next; // 其后一个
|
||||
};
|
||||
AdjList Graph[MaxVertexNum];
|
||||
int Ne,Nv;
|
||||
|
||||
// 建图
|
||||
void BuildGraph(){
|
||||
int i;
|
||||
int v1,v2,w;
|
||||
AdjList NewNode;
|
||||
scanf("%d",&Nv);
|
||||
for(i=0;i<Nv;i++){
|
||||
Graph[i] = (AdjList)malloc(sizeof(struct AdjVNode));
|
||||
Graph[i]->adjv = i;
|
||||
Graph[i]->next = NULL;
|
||||
}
|
||||
scanf("%d",&Ne);
|
||||
for(i=0;i<Ne;i++){
|
||||
scanf("%d %d %d",&v1,&v2,&w);
|
||||
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
|
||||
NewNode->adjv = v1;
|
||||
NewNode->weight = w;
|
||||
|
||||
NewNode->next = Graph[v2]->next;
|
||||
Graph[v2]->next = NewNode;
|
||||
|
||||
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
|
||||
NewNode->adjv = v2;
|
||||
NewNode->weight = w;
|
||||
|
||||
NewNode->next = Graph[v1]->next;
|
||||
Graph[v1]->next = NewNode;
|
||||
}
|
||||
}
|
||||
|
||||
void print(){
|
||||
AdjList tmp;
|
||||
int i;
|
||||
for(i=0;i<Nv;i++){
|
||||
tmp = Graph[i];
|
||||
while(tmp){
|
||||
printf("%d ",tmp->adjv);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
BuildGraph();
|
||||
print();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
上课Demo/16.图的邻接表实现.exe
Normal file
BIN
上课Demo/16.图的邻接表实现.exe
Normal file
Binary file not shown.
97
上课Demo/17.图的迷宫遍历.cpp
Normal file
97
上课Demo/17.图的迷宫遍历.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<queue>
|
||||
#define col 12
|
||||
#define row 10
|
||||
int Graph[row][col]; // 存地图
|
||||
bool visit[row][col]; // 存访问状态
|
||||
int times[row][col]; // 存访问次数
|
||||
typedef struct Node *coordinate;
|
||||
struct Node{ // 坐标
|
||||
int hor; // 横坐标
|
||||
int ver; // 纵坐标
|
||||
};
|
||||
using namespace std;
|
||||
|
||||
// 初始化图
|
||||
void Init(){
|
||||
int tmp[row][col]= {{1,1,1,0,1,1,1,0,1,1,1,0},
|
||||
{1,0,1,1,0,0,1,0,1,0,0,0},
|
||||
{1,0,0,0,1,0,0,0,1,0,1,1},
|
||||
{1,0,1,1,1,1,1,1,1,0,0,1},
|
||||
{0,0,1,0,0,1,0,1,1,1,1,0},
|
||||
{1,1,1,0,1,1,0,0,0,1,1,1},
|
||||
{1,1,0,1,1,1,1,0,0,1,0,0},
|
||||
{0,0,0,1,0,0,1,0,1,0,1,1},
|
||||
{0,1,1,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,1,1,0,1,0,1,1}};
|
||||
for(int i=0;i<row;i++)
|
||||
for(int j=0;j<col;j++){
|
||||
times[i][j] = 1000; // 初始化成大数,往小更新
|
||||
Graph[i][j] = tmp[i][j];
|
||||
if(Graph[i][j]) // 为 1 可以访问
|
||||
visit[i][j] = true;
|
||||
else
|
||||
visit[i][j] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 初始化坐标
|
||||
coordinate create(int i,int j){
|
||||
coordinate C = (coordinate)malloc(sizeof(struct Node));
|
||||
C->hor = i;
|
||||
C->ver = j;
|
||||
return C;
|
||||
}
|
||||
|
||||
int min(int t1,int t2){
|
||||
return t1<t2?t1:t2;
|
||||
}
|
||||
|
||||
// 定义 上左、上、上右、右、右下、下、左下、左 八个位置
|
||||
|
||||
int x[] = {-1,-1,-1,0,1,1,1,0};
|
||||
int y[] = {-1,0,1,1,1,0,-1,-1};
|
||||
void BFS(){
|
||||
queue<coordinate> q;
|
||||
coordinate tmp;
|
||||
// 起点入队列
|
||||
tmp = create(0,0);
|
||||
visit[0][0] = false;
|
||||
times[0][0] = 0;
|
||||
q.push(tmp);
|
||||
while(!q.empty()){
|
||||
// 取出队列中的下标和步数
|
||||
coordinate nowNode = q.front();
|
||||
int xx = nowNode->hor;
|
||||
int yy = nowNode->ver;
|
||||
int nowtimes = times[xx][yy];
|
||||
q.pop(); // 出队
|
||||
// 得到其周围八个点的坐标
|
||||
for(int i=0;i<8;i++){
|
||||
int newx = xx + x[i];
|
||||
int newy = yy + y[i];
|
||||
// 如果在范围内
|
||||
if((newx>=0 && newx<row) &&(newy>=0 && newy<col) && visit[newx][newy] ){
|
||||
visit[newx][newy] = false; // 设置状态
|
||||
tmp = create(newx,newy);
|
||||
times[newx][newy] = min(times[newx][newy],nowtimes+1); // 更新步数
|
||||
q.push(tmp); // 入队
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(){
|
||||
Init();
|
||||
BFS();
|
||||
for(int i=0;i<row;i++){
|
||||
for(int j=0;j<col;j++)
|
||||
if(times[i][j]==1000)
|
||||
printf(" -1");
|
||||
else
|
||||
printf("%3d",times[i][j]);
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/17.图的迷宫遍历.exe
Normal file
BIN
上课Demo/17.图的迷宫遍历.exe
Normal file
Binary file not shown.
88
上课Demo/18.无权图的最短路径问题.cpp
Normal file
88
上课Demo/18.无权图的最短路径问题.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#include<cstdlib>
|
||||
#include<queue>
|
||||
#include<stack>
|
||||
#define Init -1
|
||||
#define MaxVertex 100
|
||||
int path[MaxVertex]; // 存储路径
|
||||
int dist[MaxVertex]; // 存储路径长度
|
||||
int G[MaxVertex][MaxVertex]; // 图
|
||||
int Ne; // 顶点数
|
||||
int Nv; // 边
|
||||
typedef int Vertex;
|
||||
using namespace std;
|
||||
|
||||
|
||||
void build(){
|
||||
int v1,v2;
|
||||
// 初始化点
|
||||
cin>>Nv;
|
||||
for(int i=1;i<=Nv;i++)
|
||||
for(int j=1;j<=Nv;j++)
|
||||
G[i][j] = 0;
|
||||
// 初始化路径
|
||||
for(int i=1;i<=Nv;i++)
|
||||
path[i] = Init;
|
||||
// 初始化路径长度
|
||||
for(int i=1;i<=Nv;i++)
|
||||
dist[i] = Init;
|
||||
// 初始化边
|
||||
cin>>Ne;
|
||||
for(int i=0;i<Ne;i++){
|
||||
cin>>v1>>v2;
|
||||
G[v1][v2] = 1; // 有向图!
|
||||
}
|
||||
}
|
||||
|
||||
void Unweighted(Vertex v){
|
||||
queue<Vertex> q;
|
||||
dist[v] = 0; // 将自己的距离置 0
|
||||
Vertex w;
|
||||
q.push(v);
|
||||
while(!q.empty()){
|
||||
w = q.front();
|
||||
q.pop();
|
||||
for(int i=1;i<=Nv;i++)
|
||||
// 如果没被访问过,且连通
|
||||
if(dist[i]==Init && G[w][i]){
|
||||
dist[i] = dist[w]+1; // 是上一步的距离 + 1
|
||||
path[i] = w; // w 是上一步要走路径的下一步路径
|
||||
q.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取路径
|
||||
void getTail(Vertex v){
|
||||
for(int i=1;i<=Nv;i++){
|
||||
if(i==v)
|
||||
continue;
|
||||
stack<Vertex> s;
|
||||
cout<<v<<"到"<<i<<"的最短距离是:"<<dist[i];
|
||||
Vertex w = i;
|
||||
// 当没到达起始起点前一直做循环
|
||||
while(path[w]!=Init){
|
||||
s.push(w); // 入栈
|
||||
w = path[w];
|
||||
}
|
||||
// 逆序输出入栈元素,得到路径
|
||||
cout<<" 其路径为:";
|
||||
if(v != i)
|
||||
cout<<v;
|
||||
while(!s.empty()){
|
||||
// 输出栈顶元素
|
||||
cout<<"→"<<s.top();
|
||||
s.pop(); // 出栈
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Unweighted(3);
|
||||
getTail(3);
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/18.无权图的最短路径问题.exe
Normal file
BIN
上课Demo/18.无权图的最短路径问题.exe
Normal file
Binary file not shown.
94
上课Demo/19.Dijkstra.cpp
Normal file
94
上课Demo/19.Dijkstra.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#define Inf 1000000
|
||||
#define Init -1
|
||||
#define MaxVertex 100
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int dist[MaxVertex]; // 距离
|
||||
int path[MaxVertex]; // 路径
|
||||
int collected[MaxVertex]; // 被收录集合
|
||||
int Nv; // 顶点
|
||||
int Ne; // 边
|
||||
using namespace std;
|
||||
|
||||
// 初始化图信息
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>Nv;
|
||||
// 初始化图
|
||||
for(int i=1;i<=Nv;i++)
|
||||
for(int j=1;j<=Nv;j++)
|
||||
G[i][j] = 0;
|
||||
// 初始化路径
|
||||
for(int i=1;i<=Nv;i++)
|
||||
path[i] = Init;
|
||||
// 初始化距离
|
||||
for(int i=0;i<=Nv;i++)
|
||||
dist[i] = Inf;
|
||||
// 初始化收录情况
|
||||
for(int i=1;i<=Nv;i++)
|
||||
collected[i] = false;
|
||||
cin>>Ne;
|
||||
// 初始化点
|
||||
for(int i=0;i<Ne;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w; // 有向图
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化距离和路径信息
|
||||
void crate(Vertex s){
|
||||
dist[s] = 0;
|
||||
collected[s] = true;
|
||||
for(int i=1;i<=Nv;i++)
|
||||
if(G[s][i]){
|
||||
dist[i] = G[s][i];
|
||||
path[i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找未收录顶点中dist最小者
|
||||
Vertex FindMin(Vertex s){
|
||||
int min = 0; // 之前特地把 dist[0] 初始化为正无穷
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
if(i != s && dist[i] < dist[min] && !collected[i])
|
||||
min = i;
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
void Dijkstra(Vertex s){
|
||||
crate(s);
|
||||
while(true){
|
||||
Vertex V = FindMin(s); // 找到
|
||||
if(!V)
|
||||
break;
|
||||
collected[V] = true; //收录
|
||||
for(Vertex W=1;W<=Nv;W++)
|
||||
if(!collected[W] && G[V][W]){ // 如果未被收录
|
||||
if(dist[V] + G[V][W] < dist[W]){
|
||||
dist[W] = G[V][W] + dist[V];
|
||||
path[W] = V;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void output(){
|
||||
for(int i=1;i<=Nv;i++)
|
||||
cout<<dist[i]<<" ";
|
||||
cout<<endl;
|
||||
for(int i=1;i<=Nv;i++)
|
||||
cout<<path[i]<<" ";
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Dijkstra(1);
|
||||
output();
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/19.Dijkstra.exe
Normal file
BIN
上课Demo/19.Dijkstra.exe
Normal file
Binary file not shown.
111
上课Demo/2.数组存储的线性表.c
Normal file
111
上课Demo/2.数组存储的线性表.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
#define MAXSIZE 100 // MAXSIZE 定义为 Data 数组的大小
|
||||
typedef int ElementType; // ElementType 可定义为任意类型
|
||||
typedef struct LNode *List;
|
||||
struct LNode{
|
||||
ElementType Data[MAXSIZE];
|
||||
int Last; // Last 定义线性表的最后一个元素
|
||||
};
|
||||
List L;
|
||||
//访问下标为 i 的元素:L->Data[i]
|
||||
//线性表的长度:L->Last+1
|
||||
|
||||
List MakeEmpty(); //初始化顺序表
|
||||
int Find(ElementType X,List L); //查找 X 第一次出现的下标
|
||||
void Insert(ElementType X,int i,List L); //在下标为 i 的地方插入 X
|
||||
void Delete(int i,List L); //删除下标为 i 的当前值
|
||||
ElementType FindKth(int K,List L); //返回下标为 K 的当前值
|
||||
int Length(List L); //返回顺序表的长度
|
||||
|
||||
//初始化
|
||||
List MakeEmpty(){
|
||||
List L;
|
||||
L = (List)malloc(sizeof(struct LNode));
|
||||
L->Last = -1;
|
||||
return L;
|
||||
}
|
||||
|
||||
// 按值查找
|
||||
int Find(ElementType X,List L){
|
||||
int i=0;
|
||||
while(i <= L->Last && L->Data[i] != X)
|
||||
i++;
|
||||
if(L->Last < i) //如果没找到,返回 -1
|
||||
return -1;
|
||||
else // 找到后返回下标
|
||||
return i;
|
||||
}
|
||||
|
||||
// 插入
|
||||
void Insert(ElementType X,int i,List L){
|
||||
int j;
|
||||
if(L->Last == MAXSIZE-1){ //位置已满
|
||||
printf("表满");
|
||||
return;
|
||||
}
|
||||
if(i < 0 || L->Last+1 < i){ //位置越界,如果将数插入 L->Data[L->Last+1],下面都不用腾位置了
|
||||
printf("位置不合法");
|
||||
return;
|
||||
}
|
||||
for(j=L->Last;j>=i;j--) // 从后往前依次向后挪一个,给 a[i]腾出位置
|
||||
L->Data[j+1] = L->Data[j];
|
||||
L->Data[i] = X; //新元素插入
|
||||
L->Last++; // Last仍然指向最后元素
|
||||
return;
|
||||
}
|
||||
|
||||
//删除
|
||||
void Delete(int i,List L){
|
||||
int j;
|
||||
if(i < 0 || L->Last <i){ //位置越界,而删除最多到 L->Data[L->Last]
|
||||
printf("L->Data[%d]不存在元素",i);
|
||||
return;
|
||||
}
|
||||
for(j=i;j<=L->Last;j++) // 从前往后依次向前挪一个,将 a[i] 覆盖了
|
||||
L->Data[j-1] = L->Data[j];
|
||||
L->Last--; // Last仍然指向最后元素
|
||||
return;
|
||||
}
|
||||
|
||||
// 按序查找
|
||||
ElementType FindKth(int K,List L){
|
||||
if(K < 0 || L->Last < K){ //位置越界
|
||||
printf("L->Data[%d]不存在元素",K);
|
||||
return;
|
||||
}
|
||||
return L->Data[K];
|
||||
}
|
||||
|
||||
//表长
|
||||
int Length(List L){
|
||||
return L->Last+1;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int i=0;
|
||||
L = MakeEmpty();
|
||||
Insert(11,0,L);
|
||||
printf("在线性表L-Data[0]插入11\n");
|
||||
Insert(25,0,L);
|
||||
printf("在线性表L-Data[0]插入25\n");
|
||||
Insert(33,0,L);
|
||||
printf("在线性表L-Data[0]插入33\n");
|
||||
Insert(77,0,L);
|
||||
printf("在线性表L-Data[0]插入77\n");
|
||||
printf("此时的线性表为:");
|
||||
for(i=0;i<Length(L);i++)
|
||||
printf("%d ",L->Data[i]);
|
||||
printf("\n");
|
||||
printf("查找值为12的下标是:%d\n",Find(12,L));
|
||||
printf("下标为3的线性表的值是:%d\n",FindKth(3,L));
|
||||
Delete(2,L);
|
||||
printf("删除线性表中下标为2的元素\n");
|
||||
Delete(2,L);
|
||||
printf("删除线性表中下标为2的元素\n");
|
||||
printf("此时的线性表为:");
|
||||
for(i=0;i<Length(L);i++)
|
||||
printf("%d ",L->Data[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/2.数组存储的线性表.exe
Normal file
BIN
上课Demo/2.数组存储的线性表.exe
Normal file
Binary file not shown.
66
上课Demo/20.Floyd.cpp
Normal file
66
上课Demo/20.Floyd.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#define INF 1000000
|
||||
#define MaxVertex 100
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int dist[MaxVertex][MaxVertex]; // 距离
|
||||
int path[MaxVertex][MaxVertex]; // 路径
|
||||
int Nv; // 顶点
|
||||
int Ne; // 边
|
||||
using namespace std;
|
||||
|
||||
// 初始化图信息
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>Nv;
|
||||
// 初始化图
|
||||
for(int i=1;i<=Nv;i++)
|
||||
for(int j=1;j<=Nv;j++)
|
||||
G[i][j] = INF;
|
||||
cin>>Ne;
|
||||
// 初始化点
|
||||
for(int i=0;i<Ne;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w;
|
||||
G[v2][v1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
void Floyd(){
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
for(Vertex j=1;j<=Nv;j++){
|
||||
dist[i][j] = G[i][j];
|
||||
path[i][j] = -1;
|
||||
}
|
||||
for(Vertex k=1;k<=Nv;k++)
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
for(Vertex j=1;j<=Nv;j++)
|
||||
if(dist[i][k] + dist[k][j] < dist[i][j]){
|
||||
dist[i][j] = dist[i][k] + dist[k][j];
|
||||
path[i][j] = k;
|
||||
}
|
||||
}
|
||||
|
||||
void output(){
|
||||
for(Vertex i=1;i<=Nv;i++){
|
||||
for(Vertex j=1;j<=Nv;j++)
|
||||
cout<<dist[i][j]<<" ";
|
||||
cout<<endl;
|
||||
}
|
||||
cout<<endl;
|
||||
for(Vertex i=1;i<=Nv;i++){
|
||||
for(Vertex j=1;j<=Nv;j++)
|
||||
cout<<path[i][j]<<" ";
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Floyd();
|
||||
output();
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/20.Floyd.exe
Normal file
BIN
上课Demo/20.Floyd.exe
Normal file
Binary file not shown.
91
上课Demo/21.Prim.cpp
Normal file
91
上课Demo/21.Prim.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
#define INF 100000
|
||||
#define MaxVertex 105
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int parent[MaxVertex]; // 并查集
|
||||
int dist[MaxVertex]; // 距离
|
||||
int Nv; // 结点
|
||||
int Ne; // 边
|
||||
int sum; // 权重和
|
||||
using namespace std;
|
||||
vector<Vertex> MST; // 最小生成树
|
||||
|
||||
// 初始化图信息
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>Nv>>Ne;
|
||||
for(int i=1;i<=Nv;i++){
|
||||
for(int j=1;j<=Nv;j++)
|
||||
G[i][j] = 0; // 初始化图
|
||||
dist[i] = INF; // 初始化距离
|
||||
parent[i] = -1; // 初始化并查集
|
||||
}
|
||||
// 初始化点
|
||||
for(int i=0;i<Ne;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w;
|
||||
G[v2][v1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
// Prim算法前的初始化
|
||||
void IniPrim(Vertex s){
|
||||
dist[s] = 0;
|
||||
MST.push_back(s);
|
||||
for(Vertex i =1;i<=Nv;i++)
|
||||
if(G[s][i]){
|
||||
dist[i] = G[s][i];
|
||||
parent[i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找未收录中dist最小的点
|
||||
Vertex FindMin(){
|
||||
int min = INF;
|
||||
Vertex xb = -1;
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
if(dist[i] && dist[i] < min){
|
||||
min = dist[i];
|
||||
xb = i;
|
||||
}
|
||||
return xb;
|
||||
}
|
||||
|
||||
void output(){
|
||||
cout<<"被收录顺序:"<<endl;
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
cout<<MST[i]<<" ";
|
||||
cout<<"权重和为:"<<sum<<endl;
|
||||
cout<<"该生成树为:"<<endl;
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
cout<<parent[i]<<" ";
|
||||
}
|
||||
|
||||
void Prim(Vertex s){
|
||||
IniPrim(s);
|
||||
while(1){
|
||||
Vertex v = FindMin();
|
||||
if(v == -1)
|
||||
break;
|
||||
sum += dist[v];
|
||||
dist[v] = 0;
|
||||
MST.push_back(v);
|
||||
for(Vertex w=1;w<=Nv;w++)
|
||||
if(G[v][w] && dist[w])
|
||||
if(G[v][w] < dist[w]){
|
||||
dist[w] = G[v][w];
|
||||
parent[w] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Prim(1);
|
||||
output();
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/21.Prim.exe
Normal file
BIN
上课Demo/21.Prim.exe
Normal file
Binary file not shown.
98
上课Demo/22.Kruskal.cpp
Normal file
98
上课Demo/22.Kruskal.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<vector>
|
||||
#include<queue>
|
||||
#define INF 100000
|
||||
#define MaxVertex 105
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int parent[MaxVertex]; // 并查集最小生成树
|
||||
int Nv; // 结点
|
||||
int Ne; // 边
|
||||
int sum; // 权重和
|
||||
using namespace std;
|
||||
struct Node{
|
||||
Vertex v1;
|
||||
Vertex v2;
|
||||
int weight; // 权重
|
||||
// 重载运算符成最大堆
|
||||
bool operator < (const Node &a) const
|
||||
{
|
||||
return weight>a.weight;
|
||||
}
|
||||
};
|
||||
vector<Node> MST; // 最小生成树
|
||||
priority_queue<Node> q; // 最小堆
|
||||
|
||||
// 初始化图信息
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>Nv>>Ne;
|
||||
for(int i=1;i<=Nv;i++){
|
||||
for(int j=1;j<=Nv;j++)
|
||||
G[i][j] = 0; // 初始化图
|
||||
parent[i] = -1;
|
||||
}
|
||||
// 初始化点
|
||||
for(int i=0;i<Ne;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
struct Node tmpE;
|
||||
tmpE.v1 = v1;
|
||||
tmpE.v2 = v2;
|
||||
tmpE.weight = w;
|
||||
q.push(tmpE);
|
||||
}
|
||||
}
|
||||
|
||||
// 路径压缩查找
|
||||
int Find(int x){
|
||||
if(parent[x] < 0)
|
||||
return x;
|
||||
else
|
||||
return parent[x] = Find(parent[x]);
|
||||
}
|
||||
|
||||
// 按秩归并
|
||||
void Union(int x1,int x2){
|
||||
if(parent[x1] < parent[x2]){
|
||||
parent[x1] += parent[x2];
|
||||
parent[x2] = x1;
|
||||
}else{
|
||||
parent[x2] += parent[x1];
|
||||
parent[x1] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
void Kruskal(){
|
||||
// 最小生成树的边不到 Nv-1 条且还有边
|
||||
while(MST.size()!= Nv-1 && !q.empty()){
|
||||
Node E = q.top(); // 从最小堆取出一条权重最小的边
|
||||
q.pop(); // 出队这条边
|
||||
if(Find(E.v1) != Find(E.v2)){ // 检测两条边是否在同一集合
|
||||
sum += E.weight;
|
||||
Union(E.v1,E.v2); // 并起来
|
||||
MST.push_back(E);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void output(){
|
||||
cout<<"被收录顺序:"<<endl;
|
||||
for(Vertex i=0;i<Nv;i++)
|
||||
cout<<MST[i].weight<<" ";
|
||||
cout<<"权重和为:"<<sum<<endl;
|
||||
for(Vertex i=1;i<=Nv;i++)
|
||||
cout<<parent[i]<<" ";
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Kruskal();
|
||||
output();
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/22.Kruskal.exe
Normal file
BIN
上课Demo/22.Kruskal.exe
Normal file
Binary file not shown.
119
上课Demo/23.散列表数组实现.cpp
Normal file
119
上课Demo/23.散列表数组实现.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#include<cmath>
|
||||
#define MAXTABLESIZE 100000 // 定义允许开辟的最大散列表长度
|
||||
typedef int Index;
|
||||
typedef int ElementType;
|
||||
typedef Index Position;
|
||||
typedef enum{ // 分别对应:有合法元素、空、有已删除元素
|
||||
Legitimate,Empty,Deleted
|
||||
} EntryType; // 定义单元状态类型
|
||||
|
||||
typedef struct HashEntry Cell;
|
||||
struct HashEntry{ // 哈希表存值单元
|
||||
ElementType Data; // 存放元素
|
||||
EntryType Info; // 单元状态
|
||||
};
|
||||
|
||||
typedef struct HashTbl *HashTable;
|
||||
struct HashTbl{ // 哈希表结构体
|
||||
int TableSize; // 哈希表大小
|
||||
Cell *Cells; // 哈希表存值单元数组
|
||||
};
|
||||
|
||||
using namespace std;
|
||||
|
||||
int NextPrime(int N); // 查找素数
|
||||
HashTable CreateTable( int TableSize); // 创建哈希表
|
||||
Index Hash(int Key,int TableSize); // 哈希函数
|
||||
|
||||
// 查找素数
|
||||
int NextPrime(int N){
|
||||
int p = (N%2)?N+2:N+1; // 从大于 N 的下个奇数开始
|
||||
int i;
|
||||
|
||||
while(p <= MAXTABLESIZE){
|
||||
for(i = (int)sqrt(p);i>2;i--)
|
||||
if(!(p%i)) // p 不是素数
|
||||
break;
|
||||
if(i==2)
|
||||
break;
|
||||
p += 2; // 继续试探下个奇数
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
// 创建哈希表
|
||||
HashTable CreateTable( int TableSize){
|
||||
HashTable H;
|
||||
int i;
|
||||
H = (HashTable)malloc(sizeof(struct HashTbl));
|
||||
// 保证哈希表最大长度是素数
|
||||
H->TableSize = NextPrime(TableSize);
|
||||
// 初始化单元数组
|
||||
H->Cells = (Cell *)malloc(sizeof(Cell)*H->TableSize);
|
||||
// 初始化单元数组状态
|
||||
for(int i=0;i<H->TableSize;i++)
|
||||
H->Cells[i].Info = Empty;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 平方探测查找
|
||||
Position Find(HashTable H,ElementType Key){
|
||||
Position CurrentPos,NewPos;
|
||||
int CNum = 0 ; // 记录冲突次数
|
||||
CurrentPos = NewPos = Hash(Key,H->TableSize);
|
||||
// 如果当前单元状态不为空,且数值不等,则一直做
|
||||
while(H->Cells[NewPos].Info != Empty && H->Cells[NewPos].Data != Key){
|
||||
if(++CNum % 2 ){ // 冲突奇数次发生
|
||||
NewPos = CurrentPos + (CNum+1)/2*(CNum+1)/2;
|
||||
// 如果越界,一直减直到再次进入边界
|
||||
while(H->TableSize <= NewPos){
|
||||
NewPos -= H->TableSize;
|
||||
}
|
||||
}else{ // 冲突偶数次发生
|
||||
NewPos = CurrentPos - CNum/2*CNum/2;
|
||||
// 如果越界,一直加直到再次进入边界
|
||||
while(NewPos < 0){
|
||||
NewPos += H->TableSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NewPos;
|
||||
}
|
||||
|
||||
// 插入
|
||||
bool Insert( HashTable H,ElementType Key,int i){
|
||||
Position Pos = i;
|
||||
Pos = Find(H,Key);
|
||||
// 如果单元格状态不是"存在合法元素"
|
||||
if( H->Cells[Pos].Info != Legitimate){
|
||||
H->Cells[Pos].Info = Legitimate;
|
||||
H->Cells[Pos].Data = Key;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 除留余数法哈希函数
|
||||
Index Hash(int Key,int TableSize){
|
||||
return Key % TableSize;
|
||||
}
|
||||
|
||||
|
||||
void output(HashTable H){
|
||||
for(int i=0;i<H->TableSize;i++)
|
||||
cout<<i<<" "<<H->Cells[i].Data<<endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
HashTable H = CreateTable(9);
|
||||
int N;
|
||||
cin>>N;
|
||||
for(int i=0;i<N;i++){
|
||||
int tmp;
|
||||
cin>>tmp;
|
||||
Insert(H,tmp,i);
|
||||
}
|
||||
output(H);
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/23.散列表数组实现.exe
Normal file
BIN
上课Demo/23.散列表数组实现.exe
Normal file
Binary file not shown.
135
上课Demo/24.散列表链表实现.cpp
Normal file
135
上课Demo/24.散列表链表实现.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include<iostream>
|
||||
#include<cstdlib>
|
||||
#include<cmath>
|
||||
#define MAXTABLESIZE 100000
|
||||
typedef int Index;
|
||||
typedef int ElementType;
|
||||
typedef struct LNode *PtrToLNode;
|
||||
struct LNode{ // 单链表
|
||||
ElementType Data;
|
||||
PtrToLNode Next;
|
||||
};
|
||||
typedef PtrToLNode Position;
|
||||
typedef PtrToLNode List;
|
||||
|
||||
typedef struct TblNode *HashTable; // 散列表
|
||||
struct TblNode{
|
||||
int TableSize; // 表的最大长度
|
||||
List Heads; // 指向链表头结点的数组
|
||||
};
|
||||
using namespace std;
|
||||
|
||||
int NextPrime(int N){
|
||||
int p = (N%2)?(N+2):(N+1); // 比 tablesize 大的奇数
|
||||
int i;
|
||||
while(p <= MAXTABLESIZE){
|
||||
for(i = (int)sqrt(p);i>2;i--)
|
||||
if(!(p%i))
|
||||
break;
|
||||
if(i==2) // 找到素数了
|
||||
break;
|
||||
p += 2; // 下一个奇数
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
// 创建哈希表
|
||||
HashTable CreateTable( int TableSize){
|
||||
HashTable H;
|
||||
H = (HashTable)malloc(sizeof(struct TblNode));
|
||||
H->TableSize = NextPrime(TableSize);
|
||||
H->Heads = (List)malloc(sizeof(struct TblNode) * H->TableSize);
|
||||
for(int i=0;i<H->TableSize;i++)
|
||||
H->Heads[i].Next = NULL; // 链表头:H->Heads[i] 是不存东西的
|
||||
return H;
|
||||
}
|
||||
|
||||
// 除留余数法哈希函数
|
||||
Index Hash( int TableSize,ElementType Key){
|
||||
return Key%TableSize;
|
||||
}
|
||||
|
||||
// 查找
|
||||
Position Find(HashTable H,ElementType Key){
|
||||
Position p;
|
||||
Index pos;
|
||||
|
||||
pos = Hash(H->TableSize,Key);
|
||||
p = H->Heads[pos].Next; //获得链表头
|
||||
while(p && p->Data != Key)
|
||||
p = p->Next;
|
||||
return p;
|
||||
}
|
||||
|
||||
// 插入
|
||||
bool Insert(HashTable H,ElementType Key){
|
||||
Position p,NewCell;
|
||||
Index pos;
|
||||
|
||||
p = Find(H,Key);
|
||||
if(!p){ // 关键词未找到,可以插入
|
||||
NewCell = (Position)malloc(sizeof(struct LNode));
|
||||
NewCell->Data = Key;
|
||||
pos = Hash(H->TableSize,Key); // 初始散列表地址
|
||||
// 将新增结点插到最前面
|
||||
NewCell->Next = H->Heads[pos].Next;
|
||||
H->Heads[pos].Next = NewCell;
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void output(HashTable H){
|
||||
for(int i=0;i<H->TableSize;i++){
|
||||
cout<<i;
|
||||
List p = H->Heads[i].Next;
|
||||
while(p){
|
||||
cout<<" "<<p->Data;
|
||||
p = p->Next;
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyTable(HashTable H){
|
||||
Position P,tmp;
|
||||
for(int i=0;i<H->TableSize;i++){
|
||||
P = H->Heads[i].Next;
|
||||
while( P ){
|
||||
tmp = P->Next;
|
||||
free(P);
|
||||
P = tmp;
|
||||
}
|
||||
}
|
||||
free(H->Heads);
|
||||
free(H);
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
HashTable H = CreateTable(9);
|
||||
int N;
|
||||
cin>>N;
|
||||
for(int i=0;i<N;i++){
|
||||
int tmp;
|
||||
cin>>tmp;
|
||||
Insert(H,tmp);
|
||||
}
|
||||
output(H);
|
||||
DestroyTable(H);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/24.散列表链表实现.exe
Normal file
BIN
上课Demo/24.散列表链表实现.exe
Normal file
Binary file not shown.
105
上课Demo/25.KMP算法.cpp
Normal file
105
上课Demo/25.KMP算法.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 正常人实现版
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
typedef char* Position;
|
||||
#define NotFound NULL
|
||||
|
||||
char *Mystr(char* string,char *pattern){
|
||||
int Strlen = strlen(string);
|
||||
int Patlen = strlen(pattern);
|
||||
int i,j;
|
||||
int tmpi;
|
||||
for(i=0;i<Strlen;i++){
|
||||
tmpi=i;
|
||||
j=0;
|
||||
while(string[tmpi++] == pattern[j++] && j < Patlen);
|
||||
if(j==Patlen){
|
||||
return string+i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
char string[] = "this is a simple example.";
|
||||
// char string[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
char pattern[] = "simple";
|
||||
// char pattern[] = "ab";
|
||||
Position p = Mystr(string,pattern);
|
||||
if(p==NotFound)
|
||||
printf("NotFound\n");
|
||||
else
|
||||
printf("%s",p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
// KMP 算法
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
#include<stdlib.h>
|
||||
typedef int Position;
|
||||
#define NotFound -1
|
||||
using namespace std;
|
||||
|
||||
void BuildMatch(char *pattern,int *match){
|
||||
int i,j;
|
||||
int m = strlen(pattern);
|
||||
match[0] = -1;
|
||||
for(j=1;j<m;j++){
|
||||
i = match[j-1]; // 前一个字符的 match
|
||||
while((i>=0) && (pattern[i+1] != pattern[j])) // 如果不等,回退
|
||||
i = match[i];
|
||||
if(pattern[i+1] == pattern[j]) // 到某步终于等了
|
||||
match[j] = i+1; // match+1
|
||||
else // 否则前面没有相等的
|
||||
match[j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
Position KMP(char* string,char *pattern){
|
||||
int n = strlen(string);
|
||||
int m = strlen(pattern);
|
||||
int s,p;
|
||||
if(n < m)
|
||||
return NotFound;
|
||||
int *match = (int *)malloc(sizeof(int) * m);
|
||||
BuildMatch(pattern,match); // 构建 match 函数
|
||||
s = p = 0;
|
||||
while(s < n && p < m){
|
||||
if(string[s] == pattern[p]){ // 当相等时,比较下一个
|
||||
s++;
|
||||
p++;
|
||||
}else if(p>0) // 当不等了,pattern 回退到 match[p-1] + 1 的位置
|
||||
p = match[p-1]+1;
|
||||
else // 当 p = 0 时肯定没退的
|
||||
s++;
|
||||
}
|
||||
return (p == m) ? (s-m) : NotFound;
|
||||
}
|
||||
|
||||
int main(){
|
||||
char string[] = "this is a simple example.";
|
||||
// char string[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
char pattern[] = "simple";
|
||||
// char pattern[] = "ab";
|
||||
Position p = KMP(string,pattern);
|
||||
if(p==NotFound)
|
||||
printf("NotFound\n");
|
||||
else
|
||||
printf("%s",string+p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/25.KMP算法.exe
Normal file
BIN
上课Demo/25.KMP算法.exe
Normal file
Binary file not shown.
155
上课Demo/3.链表存储的线性表.c
Normal file
155
上课Demo/3.链表存储的线性表.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
typedef int ElementType; // ElementType 可定义为任意类型
|
||||
typedef struct LNode *List;
|
||||
struct LNode{
|
||||
ElementType Data; //数据域
|
||||
List Next; // 下一个链表的地址
|
||||
};
|
||||
List L;
|
||||
|
||||
List MakeEmpty(); //初始化链表
|
||||
int Length(List L); // 以遍历链表的方法求链表长度
|
||||
List FindKth(int K,List L); // 按序号查找
|
||||
List Find(ElementType X,List L); // 按值查找
|
||||
List Insert(ElementType X,int i,List L); //将 X 插入到第 i-1(i>0) 个结点之后
|
||||
List Delete(int i,List L); // 删除第 i(i>0) 个结点
|
||||
void Print(List L); // 输出链表元素
|
||||
|
||||
// 初始化链表
|
||||
List MakeEmpty(){
|
||||
List L = (List)malloc(sizeof(struct LNode));
|
||||
L = NULL;
|
||||
return L;
|
||||
}
|
||||
|
||||
//求表长
|
||||
int Length(List L){
|
||||
List p = L;
|
||||
int len=0;
|
||||
while(p){ // 当 p 不为空
|
||||
p = p->Next;
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// 按序查找
|
||||
List FindKth(int K,List L){
|
||||
List p = L;
|
||||
int i = 1; //从 1 开始
|
||||
while(p && i<K){
|
||||
p = p->Next;
|
||||
i++;
|
||||
}
|
||||
if(i == K) // 找到了
|
||||
return p;
|
||||
else // 未找到
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 按值查找
|
||||
List Find(ElementType X,List L){
|
||||
List p = L;
|
||||
while(p && p->Data!=X)
|
||||
p = p->Next;
|
||||
// 找到了,返回 p
|
||||
// 未找到,返回 NULL,此时 p 等于 NULL
|
||||
return p;
|
||||
}
|
||||
|
||||
/* 插入
|
||||
1. 用 s 指向一个新的结点
|
||||
2. 用 p 指向链表的第 i-1 个结点
|
||||
3. s->Next = p->Next,将 s 的下一个结点指向 p 的下一个结点
|
||||
4. p->Next = s,将 p 的下一结点改为 s */
|
||||
List Insert(ElementType X,int i,List L){
|
||||
List p,s;
|
||||
if(i == 1){ // 新结点插入在表头
|
||||
s = (List)malloc(sizeof(struct LNode));
|
||||
s->Data = X;
|
||||
s->Next = L;
|
||||
return s; //插入的结点为头结点
|
||||
}
|
||||
p = FindKth(i-1,L); // 找到第 i-1 个结点
|
||||
if(!p){ // 第 i-1 个结点不存在
|
||||
printf("结点错误");
|
||||
return NULL;
|
||||
}else{
|
||||
s = (List)malloc(sizeof(struct LNode));
|
||||
s->Data = X;
|
||||
s->Next = p->Next; //将 s 的下一个结点指向 p 的下一个结点
|
||||
p->Next = s; // 将 p 的下一结点改为 s
|
||||
return L;
|
||||
}
|
||||
}
|
||||
|
||||
/* 删除
|
||||
1. 用 p 指向链表的第 i-1 个结点
|
||||
2. 用 s 指向要被删除的的第 i 个结点
|
||||
3. p->Next = s->Next,p 指针指向 s 后面
|
||||
4. free(s),释放空间
|
||||
*/
|
||||
List Delete(int i,List L){
|
||||
List p,s;
|
||||
if(i==1){ //如果要删除头结点
|
||||
s = L;
|
||||
if(L) // 如果不为空
|
||||
L = L->Next;
|
||||
else
|
||||
return NULL;
|
||||
free(s); // 释放被删除结点
|
||||
return L;
|
||||
}
|
||||
p = FindKth(i-1,L); // 查找第 i-1 个结点
|
||||
if(!p || !(p->Next)){ // 第 i-1 个或第 i 个结点不存在
|
||||
printf("结点错误");
|
||||
return NULL;
|
||||
}else{
|
||||
s = p->Next; // s 指向第 i 个结点
|
||||
p->Next = s->Next; //从链表删除
|
||||
free(s); // 释放被删除结点
|
||||
return L;
|
||||
}
|
||||
}
|
||||
|
||||
// 输出链表元素
|
||||
void Print(List L){
|
||||
List t;
|
||||
int flag = 1;
|
||||
printf("当前链表为:");
|
||||
for(t = L;t;t =t->Next){
|
||||
printf("%d ",t->Data);
|
||||
flag = 0;
|
||||
}
|
||||
if(flag)
|
||||
printf("NULL");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(){
|
||||
L = MakeEmpty();
|
||||
Print(L);
|
||||
L = Insert(11,1,L);
|
||||
L = Insert(25,1,L);
|
||||
L = Insert(33,2,L);
|
||||
L = Insert(77,3,L);
|
||||
Print(L);
|
||||
printf("当前链表长度为:%d\n",Length(L));
|
||||
printf("此时链表中第二个结点的值是:%d\n",FindKth(2,L)->Data);
|
||||
printf("查找22是否在该链表中:");
|
||||
if(Find(22,L))
|
||||
printf("是!\n");
|
||||
else
|
||||
printf("否!\n");
|
||||
printf("查找33是否在该链表中:");
|
||||
if(Find(33,L))
|
||||
printf("是!\n");
|
||||
else
|
||||
printf("否!\n");
|
||||
L = Delete(1,L);
|
||||
L = Delete(3,L);
|
||||
printf("----------删除后-----\n");
|
||||
Print(L);
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/3.链表存储的线性表.exe
Normal file
BIN
上课Demo/3.链表存储的线性表.exe
Normal file
Binary file not shown.
79
上课Demo/4.栈的顺序存储实现.c
Normal file
79
上课Demo/4.栈的顺序存储实现.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
#define MaxSize 100 // 堆栈元素的最大个数
|
||||
typedef int ElementType; // ElementType 暂时定义为 int 类型
|
||||
typedef struct SNode *Stack;
|
||||
struct SNode{
|
||||
ElementType Data[MaxSize]; // 存储堆栈元素
|
||||
int Top; // 记录栈顶元素下标
|
||||
};
|
||||
|
||||
Stack CreateStack(); // 初始化堆栈
|
||||
int IsFull(Stack S); // 判断堆栈是否已满
|
||||
int IsEmpty(Stack S); // 判断堆栈是否为空
|
||||
void Push(Stack S,ElementType item); // 入栈
|
||||
ElementType Pop(Stack S); // 出栈
|
||||
|
||||
// 初始化堆栈
|
||||
Stack CreateStack(){
|
||||
Stack S;
|
||||
S = (Stack)malloc(sizeof(struct SNode));
|
||||
S->Top = -1;
|
||||
return S;
|
||||
}
|
||||
|
||||
// 是否已满
|
||||
int IsFull(Stack S){
|
||||
return (S->Top == MaxSize-1);
|
||||
}
|
||||
|
||||
// 是否为空
|
||||
int IsEmpty(Stack S){
|
||||
return (S->Top == -1);
|
||||
}
|
||||
|
||||
// 入栈
|
||||
void Push(Stack S,ElementType item){
|
||||
if(IsFull(S)){ // Top 从 0 开始
|
||||
printf("堆栈满");
|
||||
return;
|
||||
}else{
|
||||
S->Top++; // 栈顶元素加一
|
||||
S->Data[S->Top] = item; // 放进最上
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 出栈
|
||||
ElementType Pop(Stack S){
|
||||
if(IsEmpty(S)){
|
||||
printf("堆栈空");
|
||||
return;
|
||||
}else{
|
||||
ElementType val = S->Data[S->Top]; //取出最上
|
||||
S->Top--; // 栈顶元素减一
|
||||
return val;
|
||||
}
|
||||
}
|
||||
int main(){
|
||||
Stack S;
|
||||
S = CreateStack();
|
||||
printf("5入栈\n");
|
||||
Push(S,5);
|
||||
printf("7入栈\n");
|
||||
Push(S,7);
|
||||
printf("66入栈\n");
|
||||
Push(S,66);
|
||||
printf("%d出栈\n",Pop(S));
|
||||
printf("%d出栈\n",Pop(S));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/4.栈的顺序存储实现.exe
Normal file
BIN
上课Demo/4.栈的顺序存储实现.exe
Normal file
Binary file not shown.
68
上课Demo/5.栈的链表存储实现.c
Normal file
68
上课Demo/5.栈的链表存储实现.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
typedef int ElementType;
|
||||
typedef struct SNode *Stack;
|
||||
struct SNode{
|
||||
ElementType Data;
|
||||
Stack Next;
|
||||
};
|
||||
|
||||
|
||||
Stack CreateStack(); // 初始化链栈
|
||||
int IsEmpty(Stack S); // 判断链栈是否为空
|
||||
void Push(Stack S,ElementType item); // 入栈
|
||||
ElementType Pop(Stack S); // 出栈
|
||||
|
||||
|
||||
// 初始化
|
||||
Stack CreateStack(){
|
||||
Stack S;
|
||||
S = (Stack)malloc(sizeof(struct SNode));
|
||||
S->Next = NULL;
|
||||
return S;
|
||||
}
|
||||
|
||||
// 判断是否为空
|
||||
int IsEmpty(Stack S){
|
||||
return (S->Next == NULL);
|
||||
}
|
||||
|
||||
// 入栈
|
||||
void Push(Stack S,ElementType item){
|
||||
Stack tmp;
|
||||
tmp = (Stack)malloc(sizeof(struct SNode));
|
||||
tmp->Data = item;
|
||||
// 链栈栈顶元素是链表头结点,新入栈的链表在栈顶元素后面
|
||||
tmp->Next = S->Next;
|
||||
S->Next = tmp;
|
||||
}
|
||||
|
||||
// 出栈
|
||||
ElementType Pop(Stack S){
|
||||
Stack First;
|
||||
ElementType TopVal;
|
||||
if(IsEmpty(S)){
|
||||
printf("堆栈空");
|
||||
return;
|
||||
}else{
|
||||
First = S->Next; // 出栈第一个元素在栈顶元素后面
|
||||
S->Next = First->Next; //把第一个元素从链栈删除
|
||||
TopVal = First->Data; // 取出被删除结点的值
|
||||
free(First); // 释放空间
|
||||
return TopVal;
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
Stack S;
|
||||
S = CreateStack();
|
||||
printf("5入栈\n");
|
||||
Push(S,5);
|
||||
printf("7入栈\n");
|
||||
Push(S,7);
|
||||
printf("66入栈\n");
|
||||
Push(S,66);
|
||||
printf("%d出栈\n",Pop(S));
|
||||
printf("%d出栈\n",Pop(S));
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/5.栈的链表存储实现.exe
Normal file
BIN
上课Demo/5.栈的链表存储实现.exe
Normal file
Binary file not shown.
75
上课Demo/6.循环队列的顺序存储实现.c
Normal file
75
上课Demo/6.循环队列的顺序存储实现.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
#define MaxSize 100
|
||||
typedef int ElementType;
|
||||
typedef struct QNode *Queue;
|
||||
struct QNode{
|
||||
ElementType Data[MaxSize];
|
||||
int front; // 记录队头
|
||||
int rear; // 记录队尾
|
||||
};
|
||||
|
||||
Queue CreateQueue(); // 初始化队列
|
||||
void AddQ(Queue Q,ElementType item); // 入队
|
||||
int IsFull(Queue Q); // 判断队列是否已满
|
||||
ElementType DeleteQ(Queue Q); // 出队
|
||||
int IsEmpty(Queue Q); // 判断队列是否为空
|
||||
|
||||
// 初始化
|
||||
Queue CreateQueue(){
|
||||
Queue Q;
|
||||
Q = (Queue)malloc(sizeof(struct QNode));
|
||||
Q->front = -1;
|
||||
Q->rear = -1;
|
||||
return Q;
|
||||
}
|
||||
|
||||
// 判断队列是否已满
|
||||
int IsFull(Queue Q){
|
||||
return ((Q->rear+1) % MaxSize == Q->front);
|
||||
}
|
||||
|
||||
// 入队
|
||||
void AddQ(Queue Q,ElementType item){
|
||||
if(IsFull(Q)){
|
||||
printf("队列满");
|
||||
return;
|
||||
}else{
|
||||
Q->rear = (Q->rear+1) % MaxSize;
|
||||
Q->Data[Q->rear] = item;
|
||||
}
|
||||
}
|
||||
|
||||
//判断队列是否为空
|
||||
int IsEmpty(Queue Q){
|
||||
return (Q->front == Q->rear);
|
||||
}
|
||||
|
||||
// 出队
|
||||
ElementType DeleteQ(Queue Q){
|
||||
if(IsEmpty(Q)){
|
||||
printf("队列空");
|
||||
return 0;
|
||||
}else{
|
||||
Q->front = (Q->front+1) % MaxSize;
|
||||
return Q->Data[Q->front];
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
Queue Q;
|
||||
Q = CreateQueue();
|
||||
AddQ(Q,3);
|
||||
printf("3入队\n");
|
||||
AddQ(Q,5);
|
||||
printf("5入队\n");
|
||||
AddQ(Q,11);
|
||||
printf("11入队\n");
|
||||
printf("%d出队\n",DeleteQ(Q));
|
||||
printf("%d出队\n",DeleteQ(Q));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/6.循环队列的顺序存储实现.exe
Normal file
BIN
上课Demo/6.循环队列的顺序存储实现.exe
Normal file
Binary file not shown.
97
上课Demo/7.队列的链式存储实现.c
Normal file
97
上课Demo/7.队列的链式存储实现.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
typedef int ElementType;
|
||||
typedef struct QNode *Queue;
|
||||
struct Node{
|
||||
ElementType Data;
|
||||
struct Node *Next;
|
||||
};
|
||||
struct QNode{
|
||||
struct Node *rear; // 指向队尾结点
|
||||
struct Node *front; // 指向队头结点
|
||||
};
|
||||
|
||||
Queue CreateQueue(); // 初始化队列
|
||||
void AddQ(Queue Q,ElementType item); // 入队
|
||||
ElementType DeleteQ(Queue Q); // 出队
|
||||
int IsEmpty(Queue Q); // 判断队列是否为空
|
||||
|
||||
// 初始化
|
||||
Queue CreateQueue(){
|
||||
Queue Q;
|
||||
Q = (Queue)malloc(sizeof(struct QNode));
|
||||
Q->front = NULL;
|
||||
Q->rear = NULL;
|
||||
return Q;
|
||||
}
|
||||
|
||||
// 是否为空
|
||||
int IsEmpty(Queue Q){
|
||||
return (Q->front == NULL);
|
||||
}
|
||||
|
||||
// 入队
|
||||
void AddQ(Queue Q,ElementType item){
|
||||
struct Node *node;
|
||||
node = (struct Node *)malloc(sizeof(struct Node));
|
||||
node->Data = item;
|
||||
node->Next = NULL;
|
||||
if(Q->rear==NULL){ //此时队列空
|
||||
Q->rear = node;
|
||||
Q->front = node;
|
||||
}else{ //不为空
|
||||
Q->rear->Next = node; // 将结点入队
|
||||
Q->rear = node; // rear 仍然保持最后
|
||||
}
|
||||
}
|
||||
|
||||
// 出队
|
||||
ElementType DeleteQ(Queue Q){
|
||||
struct Node *FrontCell;
|
||||
ElementType FrontElem;
|
||||
if(IsEmpty(Q)){
|
||||
printf("队列空");
|
||||
return 0;
|
||||
}
|
||||
FrontCell = Q->front;
|
||||
if(Q->front == Q->rear){ // 队列中只有一个元素
|
||||
Q->front = Q->rear = NULL;
|
||||
}else{
|
||||
Q->front = Q->front->Next;
|
||||
}
|
||||
FrontElem = FrontCell->Data;
|
||||
free(FrontCell);
|
||||
return FrontElem;
|
||||
}
|
||||
|
||||
int main(){
|
||||
Queue Q;
|
||||
Q = CreateQueue();
|
||||
printf("入队5\n");
|
||||
AddQ(Q,5);
|
||||
printf("入队4\n");
|
||||
AddQ(Q,4);
|
||||
printf("入队4\n");
|
||||
AddQ(Q,3);
|
||||
printf("出队%d\n",DeleteQ(Q));
|
||||
printf("出队%d\n",DeleteQ(Q));
|
||||
printf("出队%d\n",DeleteQ(Q));
|
||||
printf("%d\n",DeleteQ(Q));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/7.队列的链式存储实现.exe
Normal file
BIN
上课Demo/7.队列的链式存储实现.exe
Normal file
Binary file not shown.
265
上课Demo/8.树的链表存储实现.cpp
Normal file
265
上课Demo/8.树的链表存储实现.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
#include<vector>
|
||||
#include<queue>
|
||||
#include<algorithm>
|
||||
typedef struct TreeNode *BinTree;
|
||||
struct TreeNode{
|
||||
int Data; // 存值
|
||||
BinTree Left; // 左儿子结点
|
||||
BinTree Right; // 右儿子结点
|
||||
};
|
||||
BinTree CreatBinTree(); // 创建一个二叉树
|
||||
bool IsEmpty(BinTree BT); // 判断树 BT 是否为空
|
||||
void PreOrderTraversal(BinTree BT); // 先序遍历,根左右
|
||||
void InOrderTraversal(BinTree BT); // 中序遍历,左根右
|
||||
void PostOrderTraversal(BinTree BT); // 后序遍历,左右根
|
||||
using namespace std;
|
||||
typedef struct SNode *Stack;
|
||||
struct SNode{
|
||||
BinTree Data;
|
||||
Stack Next;
|
||||
};
|
||||
|
||||
|
||||
Stack CreateStack(); // 初始化链栈
|
||||
int IsEmpty(Stack S); // 判断链栈是否为空
|
||||
void Push(Stack S,BinTree item); // 入栈
|
||||
BinTree Pop(Stack S); // 出栈
|
||||
|
||||
|
||||
// 初始化
|
||||
Stack CreateStack(){
|
||||
Stack S;
|
||||
S = (Stack)malloc(sizeof(struct SNode));
|
||||
S->Next = NULL;
|
||||
return S;
|
||||
}
|
||||
|
||||
// 判断是否为空
|
||||
int IsEmpty(Stack S){
|
||||
return (S->Next == NULL);
|
||||
}
|
||||
|
||||
// 入栈
|
||||
void Push(Stack S,BinTree item){
|
||||
Stack tmp;
|
||||
tmp = (Stack)malloc(sizeof(struct SNode));
|
||||
tmp->Data = item;
|
||||
// 链栈栈顶元素是链表头结点,新入栈的链表在栈顶元素后面
|
||||
tmp->Next = S->Next;
|
||||
S->Next = tmp;
|
||||
}
|
||||
|
||||
// 出栈
|
||||
BinTree Pop(Stack S){
|
||||
Stack First;
|
||||
BinTree TopVal;
|
||||
if(IsEmpty(S)){
|
||||
printf("堆栈空");
|
||||
return 0;
|
||||
}else{
|
||||
First = S->Next; // 出栈第一个元素在栈顶元素后面
|
||||
S->Next = First->Next; //把第一个元素从链栈删除
|
||||
TopVal = First->Data; // 取出被删除结点的值
|
||||
free(First); // 释放空间
|
||||
return TopVal;
|
||||
}
|
||||
}
|
||||
|
||||
BinTree Insert(int Data){
|
||||
BinTree BT;
|
||||
BT = (BinTree)malloc(sizeof(struct TreeNode));
|
||||
BT->Data = Data;
|
||||
BT->Left = NULL;
|
||||
BT->Right = NULL;
|
||||
return BT;
|
||||
}
|
||||
|
||||
// 初始化二叉树
|
||||
BinTree CreatBinTree(){
|
||||
BinTree BT;
|
||||
BT = (BinTree)malloc(sizeof(struct TreeNode));
|
||||
BT->Data = 1;
|
||||
BT->Left = Insert(2);
|
||||
BT->Right = Insert(3);
|
||||
BT->Left->Left = Insert(4);
|
||||
BT->Left->Right = Insert(6);
|
||||
BT->Left->Right->Left = Insert(5);
|
||||
BT->Right->Left = Insert(7);
|
||||
BT->Right->Right = Insert(9);
|
||||
BT->Right->Left->Right = Insert(8);
|
||||
return BT;
|
||||
}
|
||||
|
||||
|
||||
// 判断树是否为空
|
||||
/*bool IsEmpty(BinTree BT){
|
||||
}*/
|
||||
|
||||
// 先序
|
||||
/*void PreOrderTraversal(BinTree BT){
|
||||
if(BT){
|
||||
printf("%d",BT->Data); // 打印根
|
||||
PreOrderTraversal(BT->Left); // 进入左子树
|
||||
PreOrderTraversal(BT->Right); // 进入右子树
|
||||
}
|
||||
} */
|
||||
|
||||
// 先序非递归
|
||||
void PreOrderTraversal(BinTree BT){
|
||||
BinTree T = BT;
|
||||
Stack S = CreateStack(); // 创建并初始化堆栈 S
|
||||
while(T || !IsEmpty(S)){ // 当树不为空或堆栈不空
|
||||
while(T){
|
||||
Push(S,T); // 压栈,第一次遇到该结点
|
||||
printf("%d",T->Data); // 访问结点
|
||||
T = T->Left; // 遍历左子树
|
||||
}
|
||||
if(!IsEmpty(S)){ // 当堆栈不空
|
||||
T = Pop(S); // 出栈,第二次遇到该结点
|
||||
T = T->Right; // 访问右结点
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 中序递归
|
||||
/*void InOrderTraversal(BinTree BT){
|
||||
if(BT){
|
||||
InOrderTraversal(BT->Left); // 进入左子树
|
||||
printf("%d",BT->Data); // 打印根
|
||||
InOrderTraversal(BT->Right); // 进入右子树
|
||||
}
|
||||
} */
|
||||
|
||||
// 中序非递归
|
||||
void InOrderTraversal(BinTree BT){
|
||||
BinTree T = BT;
|
||||
Stack S = CreateStack(); // 创建并初始化堆栈 S
|
||||
while(T || !IsEmpty(S)){ // 当树不为空或堆栈不空
|
||||
while(T){
|
||||
Push(S,T); // 压栈
|
||||
T = T->Left; // 遍历左子树
|
||||
}
|
||||
if(!IsEmpty(S)){ // 当堆栈不空
|
||||
T = Pop(S); // 出栈
|
||||
printf("%d",T->Data); // 访问结点
|
||||
T = T->Right; // 访问右结点
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 后序
|
||||
/*void PostOrderTraversal(BinTree BT){
|
||||
if(BT){
|
||||
PostOrderTraversal(BT->Left); // 进入左子树
|
||||
PostOrderTraversal(BT->Right); // 进入右子树
|
||||
printf("%d",BT->Data); // 打印根
|
||||
}
|
||||
} */
|
||||
|
||||
// 后序遍历
|
||||
void PostOrderTraversal(BinTree BT){
|
||||
BinTree T = BT;
|
||||
Stack S = CreateStack(); // 创建并初始化堆栈 S
|
||||
vector<BinTree> v;
|
||||
Push(S,T);
|
||||
while(!IsEmpty(S)){ // 当树不为空或堆栈不空
|
||||
T = Pop(S);
|
||||
v.push_back(T);
|
||||
if(T->Left)
|
||||
Push(S,T->Left);
|
||||
if(T->Right)
|
||||
Push(S,T->Right);
|
||||
}
|
||||
reverse(v.begin(),v.end()); // 逆转
|
||||
for(int i=0;i<v.size();i++)
|
||||
printf("%d",v[i]->Data);
|
||||
}
|
||||
|
||||
// 层次遍历
|
||||
void LevelOrderTraversal(BinTree BT){
|
||||
queue<BinTree> q;
|
||||
BinTree T;
|
||||
if(!BT)
|
||||
return;
|
||||
q.push(BT); // BT 入队
|
||||
while(!q.empty()){
|
||||
T = q.front(); // 访问队首元素
|
||||
q.pop(); // 出队
|
||||
printf("%d",T->Data);
|
||||
if(T->Left)
|
||||
q.push(T->Left);
|
||||
if(T->Right)
|
||||
q.push(T->Right);
|
||||
}
|
||||
}
|
||||
// 输出叶子结点
|
||||
void FindLeaves(BinTree BT){
|
||||
if(BT){
|
||||
if( !BT->Left && !BT->Right)
|
||||
printf("%d",BT->Data); // 打印叶子结点
|
||||
FindLeaves(BT->Left); // 进入左子树
|
||||
FindLeaves(BT->Right); // 进入右子树
|
||||
}
|
||||
}
|
||||
|
||||
// 求树高度
|
||||
int GetHeight(BinTree BT){
|
||||
int hl,hr,maxh;
|
||||
if(BT){
|
||||
hl = GetHeight(BT->Left); // 求左子树高度
|
||||
hr = GetHeight(BT->Right); // 求右子树高度
|
||||
maxh = (hl>hr)?hl:hr;
|
||||
return maxh+1; // 当前结点高度为左右子树最大的高度+1
|
||||
}else
|
||||
return 0;
|
||||
}
|
||||
int main(){
|
||||
BinTree BT,ST;
|
||||
BT = CreatBinTree();
|
||||
printf("先序遍历:");
|
||||
PreOrderTraversal(BT);
|
||||
printf("\n中序遍历:");
|
||||
InOrderTraversal(BT);
|
||||
printf("\n后序遍历:");
|
||||
PostOrderTraversal(BT);
|
||||
printf("\n层次遍历:");
|
||||
LevelOrderTraversal(BT);
|
||||
printf("\n输出叶子结点:");
|
||||
FindLeaves(BT);
|
||||
printf("\n输出树的高度:%d",GetHeight(BT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
上课Demo/8.树的链表存储实现.exe
Normal file
BIN
上课Demo/8.树的链表存储实现.exe
Normal file
Binary file not shown.
150
上课Demo/9.二叉搜索树的操作.cpp
Normal file
150
上课Demo/9.二叉搜索树的操作.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
using namespace std;
|
||||
typedef int ElementType;
|
||||
typedef struct TreeNode *BinTree;
|
||||
struct TreeNode{
|
||||
ElementType Data;
|
||||
BinTree Left;
|
||||
BinTree Right;
|
||||
};
|
||||
|
||||
// 查找递归实现
|
||||
BinTree Find(ElementType X,BinTree BST){
|
||||
if(!BST) // 如果根结点为空,返回 NULL
|
||||
return NULL;
|
||||
if(X < BST->Data) // 比根结点小,去左子树查找
|
||||
return Find(X,BST->Left);
|
||||
else if(BST->Data < X) // 比根结点大,去右子树查找
|
||||
return Find(X,BST->Right);
|
||||
else if(BST->Data == X) // 找到了
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 查找非递归实现
|
||||
BinTree IterFind(ElementType X,BinTree BST){
|
||||
while(BST){
|
||||
if(X < BST->Data)
|
||||
BST = BST->Left;
|
||||
else if(BST->Data < X) // 比根结点大,去右子树查找
|
||||
BST = BST->Right;
|
||||
else if(BST->Data == X) // 找到了
|
||||
return BST;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 查找最小值的递归实现
|
||||
BinTree FindMin(BinTree BST){
|
||||
if(!BST) // 如果为空了,返回 NULL
|
||||
return NULL;
|
||||
else if(BST->Left) // 还存在左子树,沿左分支继续查找
|
||||
return FindMin(BST->Left);
|
||||
else // 找到了
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 查找最大值的非递归实现
|
||||
BinTree FindMax(BinTree BST){
|
||||
if(BST) // 如果不空
|
||||
while(BST->Right) // 只要右子树还存在
|
||||
BST = BST->Right;
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 插入
|
||||
BinTree Insert(ElementType X,BinTree BST){
|
||||
if(!BST){ // 如果为空,初始化该结点
|
||||
BST = (BinTree)malloc(sizeof(struct TreeNode));
|
||||
BST->Data = X;
|
||||
BST->Left = NULL;
|
||||
BST->Right = NULL;
|
||||
}else{ // 不为空
|
||||
if(X < BST->Data) // 如果小,挂在左边
|
||||
BST->Left = Insert(X,BST->Left);
|
||||
else if(BST->Data < X) // 如果大,挂在右边
|
||||
BST->Right = Insert(X,BST->Right);
|
||||
// 如果相等,什么都不用做
|
||||
}
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 删除
|
||||
BinTree Delete(ElementType X,BinTree BST){
|
||||
BinTree tmp;
|
||||
if(!BST)
|
||||
cout<<"要删除的元素未找到";
|
||||
else if(X < BST->Data) // X 比当前结点值小,在左子树继续查找删除
|
||||
BST->Left = Delete(X,BST->Left);
|
||||
else if(BST->Data < X) // x 比当前结点值大,在右子树继续查找删除
|
||||
BST->Right = Delete(X,BST->Right);
|
||||
else{ // 找到被删除结点
|
||||
if(BST->Left && BST->Right){ // 被删除结点有俩孩子结点
|
||||
tmp = FindMin(BST->Right); // 找到右子树中值最小的
|
||||
BST->Data = tmp->Data; // 用找到的值覆盖当前结点
|
||||
BST->Right = Delete(tmp->Data,BST->Right); // 把前面找到的右子树最小值结点删除
|
||||
}else{ // 被删除结点只有一个孩子结点或没有孩子结点
|
||||
tmp = BST;
|
||||
if(!BST->Left && !BST->Right) // 没有孩子结点
|
||||
BST = NULL;
|
||||
else if(BST->Left && !BST->Right) // 只有左孩子结点
|
||||
BST = BST->Left;
|
||||
else if(!BST->Left && BST->Right) // 只有右孩子结点
|
||||
BST = BST->Right;
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 中序遍历
|
||||
void InOrderTraversal(BinTree BT){
|
||||
if(BT){
|
||||
InOrderTraversal(BT->Left); // 进入左子树
|
||||
cout<<BT->Data; // 打印根
|
||||
InOrderTraversal(BT->Right); // 进入右子树
|
||||
}
|
||||
}
|
||||
int main(){
|
||||
BinTree BST = NULL;
|
||||
BST = Insert(5,BST);
|
||||
BST = Insert(7,BST);
|
||||
BST = Insert(3,BST);
|
||||
BST = Insert(1,BST);
|
||||
BST = Insert(2,BST);
|
||||
BST = Insert(4,BST);
|
||||
BST = Insert(6,BST);
|
||||
BST = Insert(8,BST);
|
||||
BST = Insert(9,BST);
|
||||
/*
|
||||
5
|
||||
/\
|
||||
3 7
|
||||
/\ /\
|
||||
1 4 6 8
|
||||
\ \
|
||||
2 9
|
||||
*/
|
||||
cout<<"中序遍历的结果是:";
|
||||
InOrderTraversal(BST);
|
||||
cout<<endl;
|
||||
cout<<"查找最小值是:"<<FindMin(BST)->Data<<endl;
|
||||
cout<<"查找最大值是:"<<FindMax(BST)->Data<<endl;
|
||||
cout<<"查找值为3的结点左子树结点值为:"<<Find(3,BST)->Left->Data<<endl;
|
||||
cout<<"查找值为7的结点右子树结点值为:"<<IterFind(7,BST)->Right->Data<<endl;
|
||||
cout<<"删除值为5的结点"<<endl;
|
||||
Delete(5,BST);
|
||||
/*
|
||||
6
|
||||
/\
|
||||
3 7
|
||||
/\ \
|
||||
1 4 8
|
||||
\ \
|
||||
2 9
|
||||
*/
|
||||
cout<<"中序遍历的结果是:";
|
||||
InOrderTraversal(BST);
|
||||
cout<<endl;
|
||||
return 0;
|
||||
}
|
||||
BIN
上课Demo/9.二叉搜索树的操作.exe
Normal file
BIN
上课Demo/9.二叉搜索树的操作.exe
Normal file
Binary file not shown.
118
编程作业/1.最大子列和问题.cpp
Normal file
118
编程作业/1.最大子列和问题.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
/* 方法一:确定子列的开头和结尾,再遍历累加,时间复杂度 O(n^3)*/
|
||||
int MaxSubseqSum1(int n,int a[]){
|
||||
int max = 0;
|
||||
for(int i=0;i<n;i++){
|
||||
for(int k=0;k<i;k++){
|
||||
int tmpSum = 0;
|
||||
for(int j=k;j<=i;j++){
|
||||
tmpSum+=a[j];
|
||||
}
|
||||
if(max < tmpSum)
|
||||
max = tmpSum;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
/* 方法二:确定子列的结尾,逐个减去子列前的数,时间复杂度 O(n^2)*/
|
||||
int MaxSubseqSum2(int n,int a[]){
|
||||
int sum[100000+5];
|
||||
int max = 0;
|
||||
sum[0]=a[0];
|
||||
for(int i=1;i<n;i++)
|
||||
sum[i]=sum[i-1]+a[i];
|
||||
for(int i=0;i<n;i++){
|
||||
int tmpSum = sum[i];
|
||||
for(int j=0;j<=i;j++){
|
||||
if(max < tmpSum)
|
||||
max = tmpSum;
|
||||
tmpSum-=a[j];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
/* 方法二:确定子列的首部,逐个累加,时间复杂度 O(n^2)*/
|
||||
int MaxSubseqSum3(int n,int a[]){
|
||||
int max = 0;
|
||||
for(int i=0;i<n;i++){
|
||||
int tmpSum = 0;
|
||||
for(int j=i;j<n;j++){
|
||||
tmpSum+=a[j];
|
||||
if(max < tmpSum)
|
||||
max = tmpSum;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
/* 方法三:直接累加,如果累加到当前的和为负数,置当前值或0,时间复杂度为 O(n)*/
|
||||
int MaxSubseqSum5(int n,int a[]){
|
||||
int max = 0;
|
||||
int tmpSum=0;
|
||||
for(int i=0;i<n;i++){
|
||||
tmpSum+=a[i];
|
||||
if(tmpSum<0){
|
||||
tmpSum=0;
|
||||
}else if(max < tmpSum){
|
||||
max = tmpSum;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/* 方法四:递归分成两份,分别求每个分割后子列的最大和,时间复杂度为 O(n*logn)*/
|
||||
/* 返回三者中最大值*/
|
||||
int Max3(int A,int B,int C){
|
||||
return (A>B)?((A>C)?A:C):((B>C)?B:C);
|
||||
}
|
||||
/* 分解成更小规模求解*/
|
||||
int DivideAndConquer(int a[],int left,int right){
|
||||
|
||||
/*递归结束条件,子列只有一个数字*/
|
||||
if(left == right){
|
||||
if(0 < a[left])
|
||||
return a[left];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 分别找到左右最大子列和*/
|
||||
int center = (left+right)/2;
|
||||
int MaxLeftSum = DivideAndConquer(a,left,center);
|
||||
int MaxRightSum = DivideAndConquer(a,center+1,right);
|
||||
|
||||
/* 再分别找左右跨界最大子列和*/
|
||||
int MaxLeftBorderSum = 0;
|
||||
int LeftBorderSum = 0;
|
||||
for(int i=center;i>=left;i--){
|
||||
LeftBorderSum += a[i];
|
||||
if(MaxLeftBorderSum < LeftBorderSum)
|
||||
MaxLeftBorderSum = LeftBorderSum;
|
||||
}
|
||||
int MaXRightBorderSum = 0;
|
||||
int RightBorderSum = 0;
|
||||
for(int i=center+1;i<=right;i++){
|
||||
RightBorderSum += a[i];
|
||||
if(MaXRightBorderSum < RightBorderSum)
|
||||
MaXRightBorderSum = RightBorderSum;
|
||||
}
|
||||
|
||||
/*最后返回分解的左边最大子列和,右边最大子列和,和跨界最大子列和三者中最大的数*/
|
||||
return Max3(MaxLeftSum,MaxRightSum,MaXRightBorderSum+MaxLeftBorderSum);
|
||||
}
|
||||
int MaxSubseqSum4(int n,int a[]){
|
||||
return DivideAndConquer(a,0,n-1);
|
||||
}
|
||||
int main(){
|
||||
int n;
|
||||
int a[100000+5];
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++)
|
||||
cin>>a[i];
|
||||
cout<<MaxSubseqSum1(n,a);
|
||||
cout<<MaxSubseqSum2(n,a);
|
||||
cout<<MaxSubseqSum3(n,a);
|
||||
cout<<MaxSubseqSum4(n,a);
|
||||
cout<<MaxSubseqSum5(n,a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
编程作业/1.最大子列和问题.exe
Normal file
BIN
编程作业/1.最大子列和问题.exe
Normal file
Binary file not shown.
75
编程作业/10.是否为同一棵搜索树.cpp
Normal file
75
编程作业/10.是否为同一棵搜索树.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<malloc.h>
|
||||
using namespace std;
|
||||
typedef struct TreeNode *BinTree;
|
||||
struct TreeNode{
|
||||
int data; // 存值
|
||||
BinTree left; // 左子树
|
||||
BinTree right; // 右子树
|
||||
};
|
||||
|
||||
// 插入一个结点
|
||||
BinTree Insert(int x,BinTree BST){
|
||||
if(!BST){ // 如果结点为空,创建并返回
|
||||
BST = (BinTree)malloc(sizeof(struct TreeNode));
|
||||
BST->data = x;
|
||||
BST->left = NULL;
|
||||
BST->right = NULL;
|
||||
}else{ // 如果结点不为空
|
||||
if(x < BST->data) // 如果 x 比当前结点的值小
|
||||
BST->left = Insert(x,BST->left); // 递归到左子树插入
|
||||
else if(BST->data < x) // 如果 x 比当前结点的值大
|
||||
BST->right = Insert(x,BST->right); // 递归到右子树插入
|
||||
// 如果相等,什么也不做
|
||||
}
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 前序遍历
|
||||
void PreOrderTraversal(BinTree BST,string &s){
|
||||
if(BST){
|
||||
|
||||
PreOrderTraversal(BST->left,s); // 进入左子树
|
||||
s += BST->data+'0'; // 将结点值保存进字符串
|
||||
PreOrderTraversal(BST->right,s); // 进入右子树
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
int n,l;
|
||||
int tmp;
|
||||
cin>>n>>l;
|
||||
while(n){ // 当 n 不为空做循环
|
||||
BinTree InitBST = NULL;
|
||||
string Initstr;
|
||||
// 每次新输入 n l 的初始插入序列
|
||||
for(int i=0;i<n;i++){
|
||||
cin>>tmp;
|
||||
InitBST = Insert(tmp,InitBST);
|
||||
}
|
||||
// Initstr 记录初始插入序列形成的树的先序遍历结果
|
||||
// 思考为什么不用中序记录?
|
||||
PreOrderTraversal(InitBST,Initstr);
|
||||
|
||||
// 后 l 行
|
||||
for(int i=0;i<l;i++){
|
||||
BinTree BST = NULL;
|
||||
string str;
|
||||
for(int j=0;j<n;j++){
|
||||
cin>>tmp;
|
||||
BST = Insert(tmp,BST);
|
||||
}
|
||||
// 每行的插入序列产生一个树,用 str 记录先序遍历结果
|
||||
PreOrderTraversal(BST,str);
|
||||
|
||||
// 再将初始序列和每次插入序列产生的值进行对比
|
||||
if(str == Initstr)
|
||||
cout<<"Yes"<<endl;
|
||||
else
|
||||
cout<<"No"<<endl;
|
||||
}
|
||||
cin>>n>>l;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/10.是否为同一棵搜索树.exe
Normal file
BIN
编程作业/10.是否为同一棵搜索树.exe
Normal file
Binary file not shown.
79
编程作业/11.Tree Traversals Again.cpp
Normal file
79
编程作业/11.Tree Traversals Again.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include<iostream>
|
||||
#include<stack>
|
||||
#include<string>
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
using namespace std;
|
||||
typedef struct TreeNode *Tree;
|
||||
struct TreeNode{
|
||||
string data;
|
||||
Tree left; // 左子树
|
||||
Tree right; // 右子树
|
||||
};
|
||||
// 初始化一个树结点
|
||||
Tree create(){
|
||||
Tree T;
|
||||
T = (Tree)malloc(sizeof(struct TreeNode));
|
||||
T->left = NULL;
|
||||
T->right = NULL;
|
||||
return T;
|
||||
}
|
||||
|
||||
// 根据中序遍历整理出这棵树
|
||||
Tree restore(Tree T){
|
||||
int n;
|
||||
string str;
|
||||
stack<Tree> s;
|
||||
Tree node = T;
|
||||
bool flag = false;
|
||||
string value;
|
||||
scanf("%d\n",&n);
|
||||
// 根节点赋值
|
||||
getline(cin,str);
|
||||
value = str.substr(5); // 从第五个开始截取
|
||||
node->data = value;
|
||||
// 根结点入栈
|
||||
s.push(node);
|
||||
for(int i=1;i<2*n;i++){
|
||||
getline(cin,str);
|
||||
if(str=="Pop"){// 如果是 pop 操作
|
||||
node = s.top();
|
||||
s.pop();
|
||||
}else{ // push
|
||||
value = str.substr(5); // 从第五个开始截取
|
||||
Tree tmp = create();
|
||||
tmp->data = value;
|
||||
if(!node->left){// 如果左儿子空,新结点就是左儿子
|
||||
node->left = tmp;
|
||||
node = node->left;
|
||||
}else if(!node->right){ // 如果右儿子空,新结点就是右儿子
|
||||
node->right = tmp;
|
||||
node = node->right;
|
||||
}
|
||||
s.push(tmp);
|
||||
}
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
// 后序递归遍历
|
||||
void bl(Tree T,bool &flag){
|
||||
if(T){
|
||||
bl(T->left,flag);
|
||||
bl(T->right,flag);
|
||||
if(!flag)
|
||||
flag = true;
|
||||
else
|
||||
cout<<" ";
|
||||
cout<<T->data;
|
||||
}
|
||||
}
|
||||
int main(){
|
||||
Tree T;
|
||||
bool flag = false;
|
||||
string str;
|
||||
T = create();
|
||||
T = restore(T);
|
||||
bl(T,flag);
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/11.Tree Traversals Again.exe
Normal file
BIN
编程作业/11.Tree Traversals Again.exe
Normal file
Binary file not shown.
137
编程作业/12.Root of AVL Tree.cpp
Normal file
137
编程作业/12.Root of AVL Tree.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
typedef struct AVLNode *AVLTree;
|
||||
struct AVLNode{
|
||||
int data; // 存值
|
||||
AVLTree left; // 左子树
|
||||
AVLTree right; // 右子树
|
||||
int height; // 树高
|
||||
};
|
||||
using namespace std;
|
||||
|
||||
// 返回最大值
|
||||
int Max(int a,int b){
|
||||
return a>b?a:b;
|
||||
}
|
||||
|
||||
// 返回树高,空树返回 -1
|
||||
int getHeight(AVLTree A){
|
||||
return A==NULL?-1:A->height;
|
||||
}
|
||||
|
||||
// LL单旋
|
||||
// 把 B 的右子树腾出来挂给 A 的左子树,再将 A 挂到 B 的右子树上去
|
||||
AVLTree LLRotation(AVLTree A){
|
||||
/*
|
||||
A
|
||||
/
|
||||
B
|
||||
/
|
||||
C
|
||||
*/
|
||||
// 此时根节点是 A
|
||||
AVLTree B = A->left; // B 为 A 的左子树
|
||||
A->left = B->right; // B 的右子树挂在 A 的左子树上
|
||||
B->right = A; // A 挂在 B 的右子树上
|
||||
A->height = Max(getHeight(A->left),getHeight(A->right)) + 1;
|
||||
B->height = Max(getHeight(B->left),A->height) + 1;
|
||||
return B; // 此时 B 为根结点了
|
||||
/*
|
||||
B
|
||||
/ \
|
||||
C A
|
||||
*/
|
||||
}
|
||||
|
||||
// RR单旋
|
||||
AVLTree RRRotation(AVLTree A){
|
||||
/*
|
||||
A
|
||||
\
|
||||
B
|
||||
\
|
||||
C
|
||||
*/
|
||||
// 此时根节点是 A
|
||||
AVLTree B = A->right;
|
||||
A->right = B->left;
|
||||
B->left = A;
|
||||
A->height = Max(getHeight(A->left),getHeight(A->right)) + 1;
|
||||
B->height = Max(getHeight(B->left),A->height) + 1;
|
||||
return B; // 此时 B 为根结点了
|
||||
/*
|
||||
B
|
||||
/ \
|
||||
A C
|
||||
*/
|
||||
}
|
||||
|
||||
// LR双旋
|
||||
AVLTree LRRotation(AVLTree A){
|
||||
/*
|
||||
A
|
||||
/
|
||||
B
|
||||
\
|
||||
C
|
||||
*/
|
||||
// 先 RR 单旋
|
||||
A->left = RRRotation(A->left);
|
||||
/*
|
||||
*/
|
||||
// 再 LL 单旋
|
||||
return LLRotation(A);
|
||||
}
|
||||
|
||||
// RL双旋
|
||||
AVLTree RLRotation(AVLTree A){
|
||||
// 先 LL 单旋
|
||||
A->right = LLRotation(A->right);
|
||||
// 再 RR 单旋
|
||||
return RRRotation(A);
|
||||
}
|
||||
|
||||
AVLTree Insert(AVLTree T,int x){
|
||||
if(!T){ // 如果该结点为空,初始化结点
|
||||
T = (AVLTree)malloc(sizeof(struct AVLNode));
|
||||
T->data = x;
|
||||
T->left = NULL;
|
||||
T->right = NULL;
|
||||
T->height = 0;
|
||||
}else{ // 否则不为空,
|
||||
if(x < T->data){ // 左子树
|
||||
T->left = Insert(T->left,x);
|
||||
if(getHeight(T->left)-getHeight(T->right)==2){ // 如果左子树和右子树高度差为 2
|
||||
if(x < T->left->data) // LL 单旋
|
||||
T = LLRotation(T);
|
||||
else if(T->left->data < x) // LR双旋
|
||||
T = LRRotation(T);
|
||||
}
|
||||
}else if(T->data < x){
|
||||
T->right = Insert(T->right,x);
|
||||
if(getHeight(T->right)-getHeight(T->left)==2){
|
||||
if(x < T->right->data) // RL 双旋
|
||||
T = RLRotation(T);
|
||||
else if(T->right->data < x) // RR单旋
|
||||
T = RRRotation(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
//更新树高
|
||||
T->height = Max(getHeight(T->left),getHeight(T->right)) + 1;
|
||||
return T;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
AVLTree T=NULL;
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++){
|
||||
int tmp;
|
||||
cin>>tmp;
|
||||
T = Insert(T,tmp);
|
||||
}
|
||||
cout<<T->data;
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/12.Root of AVL Tree.exe
Normal file
BIN
编程作业/12.Root of AVL Tree.exe
Normal file
Binary file not shown.
52
编程作业/13.Complete Binary Search Tree.cpp
Normal file
52
编程作业/13.Complete Binary Search Tree.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
#include<cmath>
|
||||
#include<vector>
|
||||
#define MaxSize 2005
|
||||
using namespace std;
|
||||
int value[MaxSize];
|
||||
int BST[MaxSize];
|
||||
|
||||
// 计算 n 个结点的树其左树结点个数
|
||||
int getLeftTreeSize(int n){
|
||||
int h =0; // 保存该结点下满二叉树的层数
|
||||
int tmp = n+1;
|
||||
while(tmp!=1){
|
||||
tmp /=2;
|
||||
h++;
|
||||
}
|
||||
int x = n-pow(2,h)+1; // 最下面一排子叶结点个数
|
||||
x = x<pow(2,h-1)?x:pow(2,h-1); // 子叶结点个数最多是 2^(h-1)
|
||||
int L = pow(2,h-1)-1+x; // 该结点个数情况下左子树的个数
|
||||
return L;
|
||||
}
|
||||
|
||||
// 填充函数
|
||||
void fill(int left,int right,int root){
|
||||
int n = right - left + 1; // 确定范围内数值个数
|
||||
if(!n)
|
||||
return;
|
||||
int L = getLeftTreeSize(n); // 找到"偏移量"
|
||||
BST[root] = value[left + L]; // 根结点的值应该是 左边界值 + 偏移量
|
||||
int leftRoot = 2 * root + 1; // 左儿子结点位置,由于从 0 开始
|
||||
int rightRoot = leftRoot + 1; // 右儿子结点位置
|
||||
fill(left,left+L-1,leftRoot); // 左子树递归
|
||||
fill(left+L+1,right,rightRoot); // 右子树递归
|
||||
}
|
||||
|
||||
int main(){
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++){
|
||||
cin>>value[i];
|
||||
}
|
||||
// 从小到大排序
|
||||
sort(value,value+n);
|
||||
fill(0,n-1,0);
|
||||
for(int i=0;i<n;i++){
|
||||
if(i)
|
||||
cout<<" ";
|
||||
cout<<BST[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/13.Complete Binary Search Tree.exe
Normal file
BIN
编程作业/13.Complete Binary Search Tree.exe
Normal file
Binary file not shown.
150
编程作业/14.二叉搜索树的操作集.cpp
Normal file
150
编程作业/14.二叉搜索树的操作集.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int ElementType;
|
||||
typedef struct TNode *Position;
|
||||
typedef Position BinTree;
|
||||
struct TNode{
|
||||
ElementType Data;
|
||||
BinTree Left;
|
||||
BinTree Right;
|
||||
};
|
||||
|
||||
void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
|
||||
void InorderTraversal( BinTree BT ); /* 中序遍历,由裁判实现,细节不表 */
|
||||
|
||||
BinTree Insert( BinTree BST, ElementType X );
|
||||
BinTree Delete( BinTree BST, ElementType X );
|
||||
Position Find( BinTree BST, ElementType X );
|
||||
Position FindMin( BinTree BST );
|
||||
Position FindMax( BinTree BST );
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
BinTree BST, MinP, MaxP, Tmp;
|
||||
ElementType X;
|
||||
int N, i;
|
||||
|
||||
BST = NULL;
|
||||
scanf("%d", &N);
|
||||
for ( i=0; i<N; i++ ) {
|
||||
scanf("%d", &X);
|
||||
BST = Insert(BST, X);
|
||||
}
|
||||
printf("Preorder:"); PreorderTraversal(BST); printf("\n");
|
||||
MinP = FindMin(BST);
|
||||
MaxP = FindMax(BST);
|
||||
scanf("%d", &N);
|
||||
for( i=0; i<N; i++ ) {
|
||||
scanf("%d", &X);
|
||||
Tmp = Find(BST, X);
|
||||
if (Tmp == NULL) printf("%d is not found\n", X);
|
||||
else {
|
||||
printf("%d is found\n", Tmp->Data);
|
||||
if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
|
||||
if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
|
||||
}
|
||||
}
|
||||
scanf("%d", &N);
|
||||
for( i=0; i<N; i++ ) {
|
||||
scanf("%d", &X);
|
||||
BST = Delete(BST, X);
|
||||
}
|
||||
printf("Inorder:"); InorderTraversal(BST); printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 插入
|
||||
BinTree Insert( BinTree BST, ElementType X ){
|
||||
if(!BST){ // 如果为空,创建新结点
|
||||
BST = (BinTree)malloc(sizeof(struct TNode));
|
||||
BST->Data = X;
|
||||
BST->Left = NULL;
|
||||
BST->Right = NULL;
|
||||
}else{
|
||||
if(X < BST->Data)
|
||||
BST->Left = Insert(BST->Left,X);
|
||||
else if(BST->Data < X)
|
||||
BST->Right = Insert(BST->Right,X);
|
||||
}
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 删除
|
||||
BinTree Delete( BinTree BST, ElementType X ){
|
||||
BinTree tmp;
|
||||
if(!BST){
|
||||
printf("Not Found\n");
|
||||
return BST;
|
||||
}else{
|
||||
if(X < BST->Data)
|
||||
BST->Left = Delete(BST->Left,X);
|
||||
else if(BST->Data < X)
|
||||
BST->Right = Delete(BST->Right,X);
|
||||
else{ // 找到要删除结点
|
||||
if(BST->Left && BST->Right){ // 如果该结点有左右儿子
|
||||
tmp = FindMin(BST->Right);
|
||||
BST->Data = tmp->Data;
|
||||
BST->Right = Delete(BST->Right,tmp->Data);
|
||||
}else{
|
||||
tmp = BST;
|
||||
if(BST->Left && !BST->Right)
|
||||
BST = BST->Left;
|
||||
else if(!BST->Left && BST->Right)
|
||||
BST = BST->Right;
|
||||
else
|
||||
BST = NULL;
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 寻找值最小结点
|
||||
Position FindMin( BinTree BST ){
|
||||
if(BST)
|
||||
while(BST->Left)
|
||||
BST = BST->Left;
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 寻找值最大结点
|
||||
Position FindMax( BinTree BST ){
|
||||
if(BST)
|
||||
while(BST->Right)
|
||||
BST = BST->Right;
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 查找
|
||||
Position Find( BinTree BST, ElementType X ){
|
||||
if(!BST){
|
||||
return NULL;
|
||||
}else if(X < BST->Data)
|
||||
return Find(BST->Left,X);
|
||||
else if(BST->Data < X)
|
||||
return Find(BST->Right,X);
|
||||
else
|
||||
return BST;
|
||||
}
|
||||
|
||||
// 先序遍历
|
||||
void PreorderTraversal( BinTree BT ){
|
||||
if(BT){
|
||||
printf(" %d",BT->Data);
|
||||
PreorderTraversal(BT->Left);
|
||||
PreorderTraversal(BT->Right);
|
||||
}
|
||||
}
|
||||
// 中序遍历
|
||||
void InorderTraversal( BinTree BT ){
|
||||
if(BT){
|
||||
|
||||
InorderTraversal(BT->Left);
|
||||
printf(" %d",BT->Data);
|
||||
InorderTraversal(BT->Right);
|
||||
}
|
||||
}
|
||||
BIN
编程作业/14.二叉搜索树的操作集.exe
Normal file
BIN
编程作业/14.二叉搜索树的操作集.exe
Normal file
Binary file not shown.
50
编程作业/15.堆中的路径.cpp
Normal file
50
编程作业/15.堆中的路径.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include<iostream>
|
||||
#include<malloc.h>
|
||||
const int MinData = -100000; // 哨兵值
|
||||
const int MaxSize = 1005; // 最大个数
|
||||
using namespace std;
|
||||
typedef struct HeapStruct *Heap;
|
||||
struct HeapStruct{
|
||||
int *data; // 存值的数组
|
||||
int size; // 当前元素个数
|
||||
int capacity; // 最大容量
|
||||
};
|
||||
|
||||
// 初始化堆
|
||||
Heap Create(){
|
||||
Heap H;
|
||||
H = (Heap)malloc(sizeof(struct HeapStruct));
|
||||
H->data = (int *)malloc(sizeof(int) * (MaxSize+1));
|
||||
H->size = 0;
|
||||
H->capacity = MaxSize;
|
||||
H->data[0] = MinData;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 插入
|
||||
void Insert(Heap H,int x){
|
||||
int i = ++H->size; // 指向数组最后一个
|
||||
for(;H->data[i/2]>x;i/=2)
|
||||
H->data[i] = H->data[i/2];
|
||||
H->data[i] = x;
|
||||
}
|
||||
|
||||
// 遍历
|
||||
void bl(Heap H){
|
||||
for(int i=1;i<=H->size;i++)
|
||||
cout<<H->data[i];
|
||||
}
|
||||
|
||||
int main(){
|
||||
Heap H;
|
||||
H = Create();
|
||||
int n;
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++){
|
||||
int t;
|
||||
cin>>t;
|
||||
Insert(H,t);
|
||||
}
|
||||
bl(H);
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/15.堆中的路径.exe
Normal file
BIN
编程作业/15.堆中的路径.exe
Normal file
Binary file not shown.
83
编程作业/16.File Transfer.cpp
Normal file
83
编程作业/16.File Transfer.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include<cstdio>
|
||||
#define MaxSize 10005
|
||||
typedef int SetType;
|
||||
using namespace std;
|
||||
// 初始化
|
||||
void Init(SetType s[],int n){
|
||||
for(int i=0;i<n;i++)
|
||||
s[i] = -1;
|
||||
}
|
||||
|
||||
// 查找
|
||||
int Find(SetType s[],int x){
|
||||
if(s[x] < 0) // 本身已经是根
|
||||
return x;
|
||||
else // 1. 找到根 2. 把根变成 x 的父结点 3.再返回根
|
||||
return s[x] = Find(s,s[x]);
|
||||
}
|
||||
|
||||
// 并
|
||||
void Union(SetType s[],int x1,int x2){
|
||||
// x1 规模更大,负数啊!
|
||||
if(s[x1] < s[x2]){
|
||||
s[x1] += s[x2]; // 两树合并,规模相加
|
||||
s[x2] = x1; // x2 挂到 x1 上
|
||||
}else{
|
||||
s[x2] += s[x1]; // 两树合并,规模相加
|
||||
s[x1] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
//连接
|
||||
void Input_connection(SetType s[]){
|
||||
int x1,x2;
|
||||
scanf("%d %d",&x1,&x2);
|
||||
int root1 = Find(s,x1-1); // 以数组下标存值,下标与存值差 1
|
||||
int root2 = Find(s,x2-1);
|
||||
if(root1 != root2)
|
||||
Union(s,root1,root2);
|
||||
}
|
||||
|
||||
//检查连接
|
||||
void check_connection(SetType s[]){
|
||||
int x1,x2;
|
||||
scanf("%d %d",&x1,&x2);
|
||||
int root1 = Find(s,x1-1);
|
||||
int root2 = Find(s,x2-1);
|
||||
if(root1 == root2)
|
||||
printf("yes\n");
|
||||
else
|
||||
printf("no\n");
|
||||
}
|
||||
|
||||
// 检查网络
|
||||
void check_network(SetType s[],int n){
|
||||
int counter = 0;
|
||||
for(int i=0;i<n;i++)
|
||||
if(s[i] < 0)
|
||||
counter++;
|
||||
if(counter == 1)
|
||||
printf("The network is connected.");
|
||||
else
|
||||
printf("There are %d components.",counter);
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
int n;
|
||||
char in;
|
||||
scanf("%d",&n);
|
||||
SetType s[MaxSize];
|
||||
Init(s,n);
|
||||
do{
|
||||
getchar(); // 接收每次多出来的回车
|
||||
scanf("%c",&in);
|
||||
switch(in){
|
||||
case 'I':Input_connection(s);break;
|
||||
case 'C':check_connection(s);break;
|
||||
case 'S':check_network(s,n);break;
|
||||
}
|
||||
}while(in != 'S');
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/16.File Transfer.exe
Normal file
BIN
编程作业/16.File Transfer.exe
Normal file
Binary file not shown.
304
编程作业/17.Huffman Codes.cpp
Normal file
304
编程作业/17.Huffman Codes.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
/*#include<queue>
|
||||
#include<map>
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
#define MaxSize 64
|
||||
using namespace std;
|
||||
priority_queue<int,vector<int>,greater<int> >q; // 定义优先队列,最前面的值最小
|
||||
map<char,int> mapp;
|
||||
struct character{
|
||||
char ch; // 字符
|
||||
int fre; // 频率
|
||||
};
|
||||
struct huffmanTree{
|
||||
char ch; // 字符
|
||||
string str; // 编码
|
||||
};
|
||||
|
||||
|
||||
// 建树
|
||||
int bulidTree(int n,character c[]){
|
||||
int weight = 0;
|
||||
// 入队
|
||||
for(int i=0;i<n;i++)
|
||||
q.push((c[i].fre));
|
||||
while(q.size()>1){
|
||||
// 取出堆顶元素
|
||||
int x = q.top();
|
||||
// 弹出堆顶元素
|
||||
q.pop();
|
||||
int y = q.top();
|
||||
q.pop();
|
||||
// 入堆
|
||||
q.push(x+y);
|
||||
weight += x+y; // 得到编码长度
|
||||
// 小权值会不断被加
|
||||
}
|
||||
q.pop();
|
||||
return weight;
|
||||
}
|
||||
bool cmp(huffmanTree a,huffmanTree b){
|
||||
return a.str.size() < b.str.size();
|
||||
}
|
||||
|
||||
// 判断是否为前缀
|
||||
bool isPrefix(huffmanTree code[],int n){
|
||||
// 按字符串长度从小到大排序
|
||||
sort(code,code+n,cmp);
|
||||
for(int i=0;i<n;i++){
|
||||
string str = code[i].str;
|
||||
for(int j=i+1;j<n;j++){ // 查找之后全部字符
|
||||
// 如果短字符串与长字符串截取相同长度相等,即为前缀
|
||||
if(code[j].str.substr(0,str.size()) == str)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void judge(int n,character c[],int weight){
|
||||
// 返回 WPL
|
||||
huffmanTree code[MaxSize];
|
||||
int codelen = 0;
|
||||
for(int i=0;i<n;i++){
|
||||
cin>>code[i].ch>>code[i].str;
|
||||
// 编码长度等于编码长度*频率总和
|
||||
codelen += mapp[code[i].ch]*code[i].str.size();
|
||||
}
|
||||
if(codelen != weight || isPrefix(code,n))
|
||||
cout<<"no"<<endl;
|
||||
else
|
||||
cout<<"yes"<<endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int n;
|
||||
int m;
|
||||
cin>>n;
|
||||
character c[MaxSize];
|
||||
for(int i=0;i<n;i++){
|
||||
cin>>c[i].ch>>c[i].fre;
|
||||
mapp[c[i].ch] = c[i].fre;
|
||||
}
|
||||
int weight = bulidTree(n,c);
|
||||
cin>>m;
|
||||
for(int i=0;i<m;i++)
|
||||
judge(n,c,weight);
|
||||
return 0;
|
||||
}*/
|
||||
#include<cstdio>
|
||||
#include<cstdlib>
|
||||
#include<string>
|
||||
#include<iostream>
|
||||
#include<map>
|
||||
#define HeapCapacity 64
|
||||
#define MinData 0
|
||||
typedef struct TreeNode *HuffmanTree;
|
||||
typedef struct Heap *MinHeap;
|
||||
struct Heap{ // 堆
|
||||
HuffmanTree *data; // 存哈夫曼树
|
||||
int size; // 堆的当前大小
|
||||
};
|
||||
struct TreeNode{ // 哈夫曼树
|
||||
int weight; // 频率
|
||||
HuffmanTree left;
|
||||
HuffmanTree right;
|
||||
};
|
||||
using namespace std;
|
||||
|
||||
MinHeap createHeap(); // 建堆
|
||||
HuffmanTree createHuffman(); // 建哈夫曼树
|
||||
void sortHeap(MinHeap H,int i); // 调整子最小堆
|
||||
void adjust(MinHeap H); // 调整堆
|
||||
MinHeap InitHeap(int n); // 初始化堆
|
||||
HuffmanTree Delete(MinHeap H); // 堆的删除
|
||||
void Insert(MinHeap H,HuffmanTree Huff); // 堆的插入
|
||||
HuffmanTree Huffman(MinHeap H); // 哈夫曼树的构造
|
||||
int WPL(HuffmanTree Huff,int depth); // 计算 HuffmanTree 的编码长度
|
||||
void PreOrderTraversal(HuffmanTree Huff); // 前序遍历
|
||||
|
||||
|
||||
map<char,int> mappp; // 保存字符到频率的映射关系
|
||||
|
||||
// 建堆
|
||||
MinHeap createHeap(){
|
||||
MinHeap H;
|
||||
H = (MinHeap)malloc(sizeof(struct Heap));
|
||||
H->data = (HuffmanTree *)malloc(sizeof(struct TreeNode) * HeapCapacity);
|
||||
H->size = 0;
|
||||
// 设置哨兵
|
||||
HuffmanTree Huff = createHuffman();
|
||||
H->data[0] = Huff;
|
||||
return H;
|
||||
}
|
||||
|
||||
// 建哈夫曼树
|
||||
HuffmanTree createHuffman(){
|
||||
HuffmanTree Huff;
|
||||
Huff = (HuffmanTree)malloc(sizeof(struct TreeNode));
|
||||
Huff->weight = MinData; // 初始化成频率最小
|
||||
Huff->left = NULL;
|
||||
Huff->right = NULL;
|
||||
return Huff;
|
||||
}
|
||||
|
||||
// 调整子最小堆
|
||||
void sortHeap(MinHeap H,int i){
|
||||
int parent,child;
|
||||
HuffmanTree Huff = H->data[i]; // 拿到当前根结点的哈夫曼树
|
||||
for(parent = i;parent*2<=H->size;parent = child){
|
||||
// 左右儿子中挑小的
|
||||
child = parent * 2;
|
||||
if((child!=H->size) && (H->data[child+1]->weight < H->data[child]->weight))
|
||||
child++;
|
||||
// 没有更小的了,结束循环
|
||||
if(Huff->weight <= H->data[child]->weight)
|
||||
break;
|
||||
// 否则把儿子结点拿上来
|
||||
H->data[parent] = H->data[child];
|
||||
}
|
||||
H->data[parent] = Huff;
|
||||
}
|
||||
|
||||
|
||||
// 调整堆
|
||||
void adjust(MinHeap H){
|
||||
// 从第一个有孩子结点的结点开始调整
|
||||
for(int i=H->size/2;i>0;i--)
|
||||
sortHeap(H,i);
|
||||
}
|
||||
|
||||
// 初始化堆
|
||||
MinHeap InitHeap(int n){
|
||||
MinHeap H =createHeap();
|
||||
HuffmanTree Huff;
|
||||
char c; // 临时保存字符
|
||||
int f; // 临时保存频率
|
||||
for(int i=0;i<n;i++){
|
||||
getchar();
|
||||
scanf("%c %d",&c,&f);
|
||||
mappp.insert(pair<char,int>(c,f)); // 把字符和频率的映射关系存进map
|
||||
Huff = createHuffman();
|
||||
Huff->weight = f;
|
||||
H->data[++H->size] = Huff;
|
||||
}
|
||||
// 调整最小堆
|
||||
adjust(H);
|
||||
return H;
|
||||
}
|
||||
|
||||
// 堆的删除
|
||||
HuffmanTree Delete(MinHeap H){
|
||||
int parent,child;
|
||||
HuffmanTree T = H->data[1]; // 拿到根结点的哈夫曼树
|
||||
HuffmanTree Huff = H->data[H->size--]; // 拿到最后一个位置的哈夫曼树
|
||||
for(parent = 1;parent*2<=H->size;parent = child){
|
||||
// 左右儿子中挑小的
|
||||
child = parent * 2;
|
||||
if((child!=H->size) && (H->data[child+1]->weight < H->data[child]->weight))
|
||||
child++;
|
||||
// 没有更小的了,结束循环
|
||||
if(Huff->weight <= H->data[child]->weight)
|
||||
break;
|
||||
// 否则把儿子结点拿上来
|
||||
H->data[parent] = H->data[child];
|
||||
}
|
||||
H->data[parent] = Huff;
|
||||
return T;
|
||||
}
|
||||
|
||||
// 堆的插入
|
||||
void Insert(MinHeap H,HuffmanTree Huff){
|
||||
int i = ++H->size;
|
||||
for(;Huff->weight < H->data[i/2]->weight;i/=2)
|
||||
H->data[i] = H->data[i/2];
|
||||
H->data[i] = Huff;
|
||||
}
|
||||
|
||||
// 哈夫曼树的构造
|
||||
HuffmanTree Huffman(MinHeap H){
|
||||
HuffmanTree Huff;
|
||||
int times = H->size;
|
||||
for(int i=1;i<times;i++){
|
||||
Huff = createHuffman();
|
||||
Huff->left = Delete(H); // 从堆中删除一个结点,作为新 T 的左子结点
|
||||
Huff->right = Delete(H); // 从堆中删除一个结点,作为新 T 的右子结点
|
||||
Huff->weight = Huff->left->weight + Huff->right->weight; // 重新计算权值
|
||||
Insert(H,Huff); // 再加进堆中
|
||||
}
|
||||
Huff = Delete(H);
|
||||
return Huff;
|
||||
}
|
||||
|
||||
// 计算 HuffmanTree 的编码长度
|
||||
int WPL(HuffmanTree Huff,int depth){
|
||||
// 如果是叶结点,返回编码长度
|
||||
if(Huff->left==NULL && Huff->right==NULL)
|
||||
return depth*Huff->weight;
|
||||
else // 否则返回其左右子结点的编码长度
|
||||
return (WPL(Huff->left,depth+1) + WPL(Huff->right,depth+1));
|
||||
}
|
||||
|
||||
// 提交
|
||||
void submit(int n,int codeLen){
|
||||
HuffmanTree Huff = createHuffman();
|
||||
HuffmanTree pre;
|
||||
int counter = 1;
|
||||
bool flag = true;
|
||||
char ch;
|
||||
string code;
|
||||
for(int i=0;i<n;i++){
|
||||
getchar();
|
||||
pre = Huff;
|
||||
// 读入每行
|
||||
scanf("%c",&ch);
|
||||
cin>>code;
|
||||
// 遍历编码
|
||||
for(int j=0;j<code.size();j++){
|
||||
if(code[j]=='0'){ // 如果当前编码为 0,左分支
|
||||
if(pre->left==NULL){ // 如果左子树不存在,创建
|
||||
pre->left =createHuffman();
|
||||
counter++;
|
||||
}
|
||||
if(pre->weight != 0)
|
||||
flag =false;
|
||||
pre = pre->left;
|
||||
}else if(code[j]=='1'){ // 如果当前编码为 0,左分支
|
||||
if(pre->right==NULL){ // 如果左子树不存在,创建
|
||||
pre->right = createHuffman();
|
||||
counter++;
|
||||
}
|
||||
if(pre->weight != 0)
|
||||
flag =false;
|
||||
pre = pre->right;
|
||||
}
|
||||
}
|
||||
if(pre->left || pre->right)
|
||||
flag = false;
|
||||
pre->weight = mappp[ch]; // 从 mapp 取出存的频率
|
||||
}
|
||||
if(counter!=2*n-1 || !flag || WPL(Huff,0) != codeLen){ // 如果结点不是 2n-1 个 或者编码长度不相等
|
||||
printf("No\n");
|
||||
return;
|
||||
}else{
|
||||
printf("Yes\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
int n,m;
|
||||
scanf("%d",&n);
|
||||
// 初始化最小堆
|
||||
MinHeap H = InitHeap(n);
|
||||
// 初始化哈夫曼树
|
||||
HuffmanTree Huff = Huffman(H);
|
||||
// 计算该哈夫曼树的编码长度
|
||||
int codeLen = WPL(Huff,0);
|
||||
scanf("%d",&m);
|
||||
for(int i=0;i<m;i++){
|
||||
submit(n,codeLen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/17.Huffman Codes.exe
Normal file
BIN
编程作业/17.Huffman Codes.exe
Normal file
Binary file not shown.
84
编程作业/18.列出连通集.cpp
Normal file
84
编程作业/18.列出连通集.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#include<queue>
|
||||
#define MaxVertex 100
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex];
|
||||
bool visit[MaxVertex];
|
||||
int Ne,Nv;
|
||||
using namespace std;
|
||||
|
||||
// 建图
|
||||
void Build(){
|
||||
cin>>Nv;
|
||||
for(int i=0;i<Nv;i++){
|
||||
visit[i] = false; // 置为未访问
|
||||
for(int j=0;j<Nv;j++)
|
||||
G[i][j] = 0;
|
||||
}
|
||||
cin>>Ne;
|
||||
for(int i=0;i<Ne;i++){
|
||||
int v1,v2;
|
||||
cin>>v1>>v2;
|
||||
G[v1][v2] = 1;
|
||||
G[v2][v1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void DFS(Vertex v){
|
||||
// 标记已访问
|
||||
visit[v] = true;
|
||||
cout<<" "<<v;
|
||||
for(int i=0;i<Nv;i++)
|
||||
if(!visit[i] && G[v][i])
|
||||
DFS(i);
|
||||
}
|
||||
|
||||
|
||||
void BFS(Vertex v){
|
||||
queue<Vertex> q;
|
||||
// 改变状态
|
||||
visit[v] = true;
|
||||
cout<<" "<<v;
|
||||
// 入队
|
||||
q.push(v);
|
||||
while(!q.empty()){
|
||||
// 出队队首元素
|
||||
Vertex tmp = q.front();
|
||||
q.pop();
|
||||
for(Vertex i=0;i<Nv;i++){
|
||||
// 如果未被访问过,且和刚出队元素相邻
|
||||
if(!visit[i] && G[i][tmp]){
|
||||
visit[i] = true;
|
||||
cout<<" "<<i;
|
||||
q.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历联通集
|
||||
void ListComp(){
|
||||
for(Vertex i=0;i<Nv;i++)
|
||||
if(!visit[i]){
|
||||
cout<<"{";
|
||||
DFS(i);
|
||||
cout<<" }"<<endl;
|
||||
}
|
||||
// 初始访问状态
|
||||
for(Vertex i=0;i<Nv;i++)
|
||||
visit[i] = false;
|
||||
|
||||
for(Vertex i=0;i<Nv;i++)
|
||||
if(!visit[i]){
|
||||
cout<<"{";
|
||||
BFS(i);
|
||||
cout<<" }"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
Build();
|
||||
ListComp();
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/18.列出连通集.exe
Normal file
BIN
编程作业/18.列出连通集.exe
Normal file
Binary file not shown.
126
编程作业/19.Saving James Bond - Easy Version.cpp
Normal file
126
编程作业/19.Saving James Bond - Easy Version.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#include<cmath>
|
||||
#include<queue>
|
||||
#define MaxVertex 105
|
||||
struct Node{ // 存鳄鱼下标
|
||||
int hor; // 横坐标
|
||||
int ver; // 纵坐标
|
||||
bool visit; // 是否被访问
|
||||
bool safe; // 是否能上岸
|
||||
bool jump; // 第一步能否跳上去
|
||||
};
|
||||
int N; // 鳄鱼数
|
||||
int D; // 跳跃距离
|
||||
bool isSafe; // 是否上岸
|
||||
Node G[MaxVertex];
|
||||
using namespace std;
|
||||
const double diameter=15;
|
||||
|
||||
// 计算两点距离
|
||||
double getLen(int x1,int y1,int x2,int y2){
|
||||
return sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0));
|
||||
}
|
||||
|
||||
// 计算该鳄鱼能否到岸边
|
||||
bool ashore(int x,int y){
|
||||
// 分别计算当前结点与岸边的距离
|
||||
// 即与 (x,50),(x,-50),(50,y),(-50,y) 的距离
|
||||
if(abs(x-50)<=D || abs(x+50)<=D || abs(y+50)<=D || abs(y-50)<=D)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 确认鳄鱼是否安全("能上岸")
|
||||
void getSafe(){
|
||||
for(int i=0;i<N;i++){
|
||||
// 如果该鳄鱼位置和"岸边"相邻
|
||||
if(ashore((G[i].hor),(G[i].ver)))
|
||||
G[i].safe = true; // 将情况置为 true
|
||||
else
|
||||
G[i].safe = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 确认哪些鳄鱼是可以第一步跳上去的
|
||||
void getJump(){
|
||||
for(int i=0;i<N;i++){
|
||||
// 如果该鳄鱼位置和"湖中心"相邻(跳跃距离+半径)
|
||||
if(getLen(G[i].hor,G[i].ver,0,0)<=D+diameter/2)
|
||||
G[i].jump = true;
|
||||
else
|
||||
G[i].jump = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
void Init(){
|
||||
cin>>N>>D;
|
||||
int x,y;
|
||||
for(int i=0;i<N;i++){
|
||||
cin>>x>>y;
|
||||
G[i].hor = x;
|
||||
G[i].ver = y;
|
||||
G[i].visit = false;
|
||||
}
|
||||
getSafe();
|
||||
getJump();
|
||||
isSafe = false;
|
||||
}
|
||||
/*
|
||||
void DFS(int v){
|
||||
if(G[v].safe){
|
||||
isSafe = true;
|
||||
return;
|
||||
}
|
||||
G[v].visit = true;
|
||||
for(int i=0;i<N;i++){
|
||||
// 距离如果小于 D,且未跳过,则能跳
|
||||
if(getLen(G[v].hor,G[v].ver,G[i].hor,G[i].ver)<=D && !G[i].visit)
|
||||
DFS(i);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void BFS(int v){
|
||||
queue<Node> q;
|
||||
Node tmp;
|
||||
G[v].visit = true;
|
||||
// 第一只鳄鱼入队
|
||||
q.push(G[v]);
|
||||
while(!q.empty()){
|
||||
tmp = q.front();
|
||||
q.pop();
|
||||
// 能上岸
|
||||
if(tmp.safe){
|
||||
isSafe = true;
|
||||
return;
|
||||
}
|
||||
for(int i=0;i<N;i++){
|
||||
// 距离如果小于 D,且未跳过,则能跳
|
||||
if(getLen(tmp.hor,tmp.ver,G[i].hor,G[i].ver)<=D && !G[i].visit){
|
||||
G[i].visit = true;
|
||||
q.push(G[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历所有第一步能跳到的鳄鱼
|
||||
void listCompoent(){
|
||||
for(int i=0;i<N;i++)
|
||||
if(G[i].jump){
|
||||
// DFS(i);
|
||||
BFS(i);
|
||||
}
|
||||
if(isSafe)
|
||||
cout<<"Yes"<<endl;
|
||||
else
|
||||
cout<<"No"<<endl;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
Init();
|
||||
listCompoent();
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/19.Saving James Bond - Easy Version.exe
Normal file
BIN
编程作业/19.Saving James Bond - Easy Version.exe
Normal file
Binary file not shown.
31
编程作业/2.Maximum Subsequence Sum.cpp
Normal file
31
编程作业/2.Maximum Subsequence Sum.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
int main(){
|
||||
int n;
|
||||
int a[100000+5];
|
||||
cin>>n;
|
||||
for(int i=0;i<n;i++)
|
||||
cin>>a[i];
|
||||
int left = 0;
|
||||
int tmpleft = 0;
|
||||
int right = n-1;
|
||||
int max =0;
|
||||
int tmpSum=0;
|
||||
for(int i=0;i<n;i++){
|
||||
tmpSum+=a[i];
|
||||
if(tmpSum<0){
|
||||
tmpSum=0;
|
||||
tmpleft = i+1; // 开头的数就在这段被抛弃子序列的下一个
|
||||
}else if(max < tmpSum){
|
||||
max = tmpSum;
|
||||
left = tmpleft; // 每次更新最大值也就确定了一段子序列,保存此时的开头
|
||||
right = i; // 结尾的数就在每次更新最大值时
|
||||
}
|
||||
}
|
||||
if(max>=0)
|
||||
cout<<max<<" "<<a[left]<<" "<<a[right];
|
||||
else
|
||||
cout<<0<<" "<<a[0]<<" "<<a[n-1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
编程作业/2.Maximum Subsequence Sum.exe
Normal file
BIN
编程作业/2.Maximum Subsequence Sum.exe
Normal file
Binary file not shown.
107
编程作业/20.六度空间.cpp
Normal file
107
编程作业/20.六度空间.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include<iostream>
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<queue>
|
||||
#define MaxVertex 10005
|
||||
typedef int vertex;
|
||||
typedef struct Node *AdjList;
|
||||
struct Node{
|
||||
vertex Adjv; // 当前下标
|
||||
AdjList Next; // 下一个
|
||||
};
|
||||
AdjList G[MaxVertex];
|
||||
bool visit[MaxVertex]; // 是否访问
|
||||
int N; // 结点数
|
||||
int M; // 边数
|
||||
using namespace std;
|
||||
|
||||
// 初始化访问状态
|
||||
void InitVisit(){
|
||||
for(int i=1;i<=N;i++)
|
||||
visit[i] = false;
|
||||
}
|
||||
|
||||
// 初始化
|
||||
void Init(){
|
||||
vertex v1,v2;
|
||||
AdjList NewNode;
|
||||
cin>>N>>M;
|
||||
// 初始化点,从 1—N
|
||||
for(int i=1;i<=N;i++){
|
||||
G[i] = (AdjList)malloc(sizeof(struct Node));
|
||||
G[i]->Adjv = i;
|
||||
G[i]->Next = NULL;
|
||||
}
|
||||
// 初始化边
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2;
|
||||
NewNode = (AdjList)malloc(sizeof(struct Node));
|
||||
NewNode->Adjv = v2;
|
||||
NewNode->Next = G[v1]->Next;
|
||||
G[v1]->Next = NewNode;
|
||||
|
||||
NewNode = (AdjList)malloc(sizeof(struct Node));
|
||||
NewNode->Adjv = v1;
|
||||
NewNode->Next = G[v2]->Next;
|
||||
G[v2]->Next = NewNode;
|
||||
}
|
||||
}
|
||||
|
||||
int BFS(vertex v){
|
||||
queue<vertex> q;
|
||||
vertex tmp;
|
||||
int level = 0;
|
||||
int last = v; // 该层最后一次访问的结点
|
||||
int tail = v; // 每次在变的结点
|
||||
AdjList node;
|
||||
visit[v] = true;
|
||||
int count = 1; // 统计关系数
|
||||
q.push(v);
|
||||
while(!q.empty()){
|
||||
tmp = q.front();
|
||||
q.pop();
|
||||
// G[i]第一个结点存自己的下标
|
||||
node = G[tmp]->Next;
|
||||
while(node){
|
||||
if(!visit[node->Adjv]){
|
||||
visit[node->Adjv] = true;
|
||||
q.push(node->Adjv);
|
||||
count++;
|
||||
tail = node->Adjv; // 每次更新该结点
|
||||
}
|
||||
node = node->Next;
|
||||
}
|
||||
// 如果该当前结点是这层最后一个结点
|
||||
if(tmp == last){
|
||||
level++; // 层数 +1
|
||||
last = tail; // 更改 last
|
||||
}
|
||||
// 层数够了结束
|
||||
if(level==6)
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void output(double result,int i){
|
||||
printf("%d: %.2f%%\n",i,result);
|
||||
}
|
||||
|
||||
void SDS(){
|
||||
int count;
|
||||
for(int i=1;i<=N;i++){
|
||||
// 每次初始化访问数组
|
||||
InitVisit();
|
||||
count = BFS(i);
|
||||
output((100.0*count)/N,i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
Init();
|
||||
SDS();
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/20.六度空间.exe
Normal file
BIN
编程作业/20.六度空间.exe
Normal file
Binary file not shown.
167
编程作业/21.哈利·波特的考试.cpp
Normal file
167
编程作业/21.哈利·波特的考试.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/*#include<iostream>
|
||||
#define MaxVertex 105
|
||||
#define INF 100000
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex]; // 图
|
||||
int N; // 动物数(顶点)
|
||||
int M; // 咒语条数(边)
|
||||
int dist[MaxVertex][MaxVertex]; // 距离
|
||||
bool collected[MaxVertex][MaxVertex]; // 选中状态
|
||||
using namespace std;
|
||||
|
||||
// 初始化
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>N>>M;
|
||||
for(Vertex i=1;i<=N;i++){
|
||||
for(Vertex j=1;j<=N;j++){
|
||||
G[i][j] = 0; // 初始化图
|
||||
dist[i][j] = INF; // 初始化距离
|
||||
collected[i][j] = false; // 初始选中状态
|
||||
}
|
||||
dist[i][0] = INF; // 特意将每个源点第一个距离初始成 INF
|
||||
}
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w;
|
||||
G[v2][v1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找未被选中的顶点中距离最小的一个
|
||||
Vertex FindMin(Vertex s){
|
||||
Vertex min = 0;
|
||||
for(Vertex i = 1;i<=N;i++)
|
||||
if(i!=s && dist[s][i] < dist[s][min] && !collected[s][i])
|
||||
min = i;
|
||||
return min;
|
||||
}
|
||||
|
||||
int FindMax(Vertex s){
|
||||
int max = 0;
|
||||
for(Vertex i = 1;i<=N;i++)
|
||||
if(max < dist[s][i])
|
||||
max = dist[s][i];
|
||||
return max;
|
||||
}
|
||||
|
||||
// 设置源点距离,且该点周围点更新状态
|
||||
void prepare(Vertex s){
|
||||
dist[s][s] = 0;
|
||||
collected[s][s] = true;
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
if(G[s][i])
|
||||
dist[s][i] = G[s][i];
|
||||
}
|
||||
|
||||
int Dijkstra(Vertex s){
|
||||
prepare(s); // 准备
|
||||
while(1){
|
||||
Vertex v = FindMin(s);
|
||||
if(!v)
|
||||
break;
|
||||
collected[s][v] = true;
|
||||
for(Vertex w=1;w<=N;w++)
|
||||
if(G[v][w] && !collected[s][w])
|
||||
if(dist[s][v] + G[v][w] < dist[s][w])
|
||||
dist[s][w] = dist[s][v] + G[v][w];
|
||||
}
|
||||
// 找到自己最难变的咒语长度
|
||||
return FindMax(s);
|
||||
}
|
||||
|
||||
int main(){
|
||||
build();
|
||||
int min = INF;
|
||||
int xb = 0;
|
||||
int max;
|
||||
for(Vertex s=1;s<=N;s++){
|
||||
max = Dijkstra(s);
|
||||
if(max < min){
|
||||
min = max;
|
||||
xb = s;
|
||||
}
|
||||
if(min==INF){
|
||||
cout<<0<<endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cout<<xb<<" "<<min<<endl;
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
#include<iostream>
|
||||
#define MaxVertex 105
|
||||
#define INF 100000
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex]; // 图
|
||||
int N; // 动物数(顶点)
|
||||
int M; // 咒语条数(边)
|
||||
int dist[MaxVertex][MaxVertex]; // 距离
|
||||
using namespace std;
|
||||
|
||||
// 初始化
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>N>>M;
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
for(Vertex j=1;j<=N;j++)
|
||||
G[i][j] = INF; // 初始化图
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w;
|
||||
G[v2][v1] = w;
|
||||
}
|
||||
}
|
||||
|
||||
void Floyd(){
|
||||
// 初始化 dist 数组
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
for(Vertex j=1;j<=N;j++)
|
||||
dist[i][j] = G[i][j];
|
||||
for(Vertex k=1;k<=N;k++)
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
for(Vertex j=1;j<=N;j++)
|
||||
if(dist[i][k] + dist[k][j] < dist[i][j])
|
||||
dist[i][j] = dist[i][k] + dist[k][j];
|
||||
}
|
||||
|
||||
// 查找每个源点到其他点的最大值
|
||||
int FindMax(Vertex s){
|
||||
int max = 0;
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
if(s!=i && max < dist[s][i])
|
||||
max = dist[s][i];
|
||||
return max;
|
||||
}
|
||||
|
||||
// 查找每个源点到其他点的最大值中最小的距离
|
||||
void FindMin(){
|
||||
int ItemMax;
|
||||
int min = INF;
|
||||
int animal;
|
||||
for(Vertex i=1;i<=N;i++){
|
||||
ItemMax = FindMax(i);
|
||||
if(ItemMax == INF){
|
||||
cout<<0<<endl;
|
||||
return;
|
||||
}
|
||||
if(ItemMax < min){
|
||||
min = ItemMax;
|
||||
animal = i;
|
||||
}
|
||||
}
|
||||
cout<<animal<<" "<<min<<endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Floyd();
|
||||
FindMin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
编程作业/21.哈利·波特的考试.exe
Normal file
BIN
编程作业/21.哈利·波特的考试.exe
Normal file
Binary file not shown.
165
编程作业/22.Saving James Bond - Hard Version.cpp
Normal file
165
编程作业/22.Saving James Bond - Hard Version.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include<iostream>
|
||||
#include<cmath>
|
||||
#define INF 100000
|
||||
#define MaxVertex 105
|
||||
typedef int Vertex;
|
||||
int G[MaxVertex][MaxVertex]; // 图
|
||||
int dist[MaxVertex]; // 距离
|
||||
int path[MaxVertex]; // 路径
|
||||
bool collected[MaxVertex]; // 收录情况
|
||||
int N; // 顶点
|
||||
int D; // 一跳距离
|
||||
struct Node{ // 存位置
|
||||
int hor; // 横坐标
|
||||
int ver; // 纵坐标
|
||||
};
|
||||
Node pos[MaxVertex]; // 存放鳄鱼位置
|
||||
const double diameter=15; // 直径
|
||||
using namespace std;
|
||||
|
||||
// 无向无权图
|
||||
// 0.判断能上岸鳄鱼的集合
|
||||
// 1.判断各个点是否连接
|
||||
// 2.转换为图
|
||||
|
||||
// 计算两点距离
|
||||
double getLen(int x1,int y1,int x2,int y2){
|
||||
return sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0));
|
||||
}
|
||||
// 判断鳄鱼能否上岸
|
||||
bool ashore(int x,int y){
|
||||
// 分别计算当前结点与岸边的距离
|
||||
// 即与 (x,50),(x,-50),(50,y),(-50,y) 的距离
|
||||
if(abs(x-50)<=D || abs(x+50)<=D || abs(y+50)<=D || abs(y-50)<=D)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 确认鳄鱼是否安全("能上岸")
|
||||
void getSafe(){
|
||||
for(int i=0;i<N;i++){
|
||||
// 如果该鳄鱼位置和"岸边"相邻
|
||||
// 连通
|
||||
if(ashore((pos[i].hor),(pos[i].ver))){
|
||||
G[N+1][i] = 1;
|
||||
G[i][N+1] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确认哪些鳄鱼是可以第一步跳上去的
|
||||
void getJump(){
|
||||
for(int i=0;i<N;i++)
|
||||
// 如果该鳄鱼位置和"湖中心"相邻(跳跃距离+半径)
|
||||
if(getLen(pos[i].hor,pos[i].ver,0,0)<=D+diameter/2){
|
||||
G[N][i] = 1;
|
||||
G[i][N] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 鳄鱼间的情况
|
||||
void getConn(){
|
||||
for(int i=0;i<N;i++)
|
||||
for(int j=0;j<N;j++)
|
||||
// 如果鳄鱼间距离小于一跳距离,则彼此连通
|
||||
if(i!=j && getLen(pos[i].hor,pos[i].ver,pos[j].hor,pos[j].ver)<=D){
|
||||
G[i][j] = 1;
|
||||
G[j][i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
void Init(){
|
||||
cin>>N>>D;
|
||||
int x,y;
|
||||
// 录入位置
|
||||
for(int i=0;i<N;i++){
|
||||
cin>>x>>y;
|
||||
pos[i].hor = x;
|
||||
pos[i].ver = y;
|
||||
}
|
||||
// 007 算顶点,岸也算顶点
|
||||
// 初始化图,007连通情况存 G[N],岸连通情况存 G[N+1]
|
||||
for(Vertex i=0;i<=N+1;i++){
|
||||
for(Vertex j=0;j<=N+1;j++)
|
||||
G[i][j] = INF; // 初始无穷大
|
||||
dist[i] = INF; // 初始化距离
|
||||
path[i] = -1; // 初始化路径
|
||||
collected[i] = false; // 初始化收录状态
|
||||
}
|
||||
// 初始化边
|
||||
// 岸连通情况
|
||||
getSafe();
|
||||
// 007连通情况
|
||||
getJump();
|
||||
// 鳄鱼彼此连通情况
|
||||
getConn();
|
||||
}
|
||||
|
||||
|
||||
// 查找未收录dist最小的点
|
||||
Vertex FindMin(Vertex s){
|
||||
int min = INF;
|
||||
Vertex xb=-1;
|
||||
for(Vertex i=0;i<=N+1;i++)
|
||||
if(s!=i && !collected[i] && dist[i] < min){
|
||||
min = dist[i];
|
||||
xb = i;
|
||||
}
|
||||
return xb;
|
||||
}
|
||||
|
||||
// 初始化源点信息
|
||||
void InitSource(Vertex s){
|
||||
dist[s] = 0;
|
||||
collected[s] = true;
|
||||
for(Vertex i=0;i<=N+1;i++)
|
||||
if(G[s][i]!=INF){
|
||||
dist[i] = G[s][i];
|
||||
path[i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
void Dijkstra(Vertex s){
|
||||
InitSource(s);
|
||||
while(1){
|
||||
Vertex v = FindMin(s);
|
||||
if(v==-1)
|
||||
break;
|
||||
collected[v] = true;
|
||||
for(Vertex w=0;w<=N+1;w++)
|
||||
if(!collected[w] && G[v][w]!=INF)
|
||||
if(dist[v] + G[v][w] < dist[w]){
|
||||
dist[w] = dist[v] + G[v][w];
|
||||
path[w] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出路径
|
||||
void outputPath(){
|
||||
// 如果不通
|
||||
|
||||
|
||||
if(dist[N+1] == INF){
|
||||
cout<<0<<endl;
|
||||
return;
|
||||
}
|
||||
Vertex v = path[N+1];
|
||||
cout<<dist[N+1]<<endl;
|
||||
while(v!=-1){
|
||||
cout<<pos[v].hor<<" "<<pos[v].ver<<endl;
|
||||
v = path[v];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(){
|
||||
Init();
|
||||
Dijkstra(N);
|
||||
outputPath();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BIN
编程作业/22.Saving James Bond - Hard Version.exe
Normal file
BIN
编程作业/22.Saving James Bond - Hard Version.exe
Normal file
Binary file not shown.
86
编程作业/23.旅游规划.cpp
Normal file
86
编程作业/23.旅游规划.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#include<iostream>
|
||||
#define MaxVertex 505
|
||||
#define INF 100000
|
||||
typedef int Vertex;
|
||||
int N; // 顶点数
|
||||
int M; // 边
|
||||
int S; // Source
|
||||
int D; // Destination
|
||||
int dist[MaxVertex]; // 距离
|
||||
int cost[MaxVertex]; // 费用
|
||||
bool collected[MaxVertex]; // 选中情况
|
||||
int value[MaxVertex][MaxVertex]; // 收费
|
||||
int G[MaxVertex][MaxVertex];
|
||||
using namespace std;
|
||||
|
||||
|
||||
void build(){
|
||||
Vertex v1,v2,w1,w2;
|
||||
cin>>N>>M>>S>>D;
|
||||
for(Vertex i=0;i<N;i++){
|
||||
for(Vertex j=0;j<N;j++){
|
||||
G[i][j] = INF;
|
||||
value[i][j] = INF;
|
||||
}
|
||||
cost[i] = 0;
|
||||
collected[i] = false;
|
||||
dist[i] = INF;
|
||||
}
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w1>>w2;
|
||||
G[v1][v2] = w1;
|
||||
G[v2][v1] = w1;
|
||||
value[v1][v2] = w2;
|
||||
value[v2][v1] = w2;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化源点信息
|
||||
void InitSource(){
|
||||
dist[S] = 0;
|
||||
collected[S] = true;
|
||||
for(Vertex i=0;i<N;i++)
|
||||
if(G[S][i]){
|
||||
dist[i] = G[S][i];
|
||||
cost[i] = value[S][i];
|
||||
}
|
||||
}
|
||||
|
||||
// 查找未被收录中dist最小的点
|
||||
Vertex FindMin(){
|
||||
int min = INF;
|
||||
Vertex xb = -1;
|
||||
for(Vertex i=0;i<N;i++)
|
||||
if(S!=i && !collected[i] && dist[i] < min){
|
||||
min = dist[i];
|
||||
xb = i;
|
||||
}
|
||||
return xb;
|
||||
}
|
||||
|
||||
void Dijkstra(){
|
||||
InitSource();
|
||||
while(1){
|
||||
Vertex v = FindMin();
|
||||
if(v==-1)
|
||||
break;
|
||||
collected[v] = true;
|
||||
for(Vertex w=0;w<N;w++)
|
||||
if(!collected[w] && G[v][w])
|
||||
if(dist[v] + G[v][w] < dist[w]){ // 如果有路径更短
|
||||
dist[w] = dist[v] + G[v][w];
|
||||
cost[w] = cost[v] + value[v][w];
|
||||
}else if(dist[v] + G[v][w] == dist[w] && cost[v] + value[v][w] < cost[w]){ // 如果路径一样长,选择费用更少
|
||||
cost[w] = cost[v] + value[v][w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Dijkstra();
|
||||
cout<<dist[D]<<" "<<cost[D];
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
编程作业/23.旅游规划.exe
Normal file
BIN
编程作业/23.旅游规划.exe
Normal file
Binary file not shown.
90
编程作业/24.公路村村通.cpp
Normal file
90
编程作业/24.公路村村通.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include<iostream>
|
||||
#include<queue>
|
||||
#include<vector>
|
||||
#define MaxVertex 1005
|
||||
typedef int Vertex;
|
||||
using namespace std;
|
||||
int N; // 顶点
|
||||
int M; // 边
|
||||
int parent[MaxVertex]; // 并查集
|
||||
struct Node{
|
||||
Vertex v1;
|
||||
Vertex v2;
|
||||
int weight;
|
||||
// 重载运算符
|
||||
bool operator < (const Node &a) const
|
||||
{
|
||||
return weight>a.weight;
|
||||
}
|
||||
};
|
||||
priority_queue<Node> q; // 最小堆
|
||||
vector<Node> MST; // 最小生成树
|
||||
int sum;
|
||||
|
||||
// 初始化图信息
|
||||
void build(){
|
||||
Vertex v1,v2;
|
||||
int w;
|
||||
cin>>N>>M;
|
||||
for(int i=1;i<=N;i++){
|
||||
parent[i] = -1;
|
||||
}
|
||||
// 初始化点
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
struct Node tmpE;
|
||||
tmpE.v1 = v1;
|
||||
tmpE.v2 = v2;
|
||||
tmpE.weight = w;
|
||||
q.push(tmpE);
|
||||
}
|
||||
sum = 0;
|
||||
}
|
||||
|
||||
|
||||
// 路径压缩查找
|
||||
int Find(int x){
|
||||
if(parent[x] < 0)
|
||||
return x;
|
||||
else
|
||||
return parent[x] = Find(parent[x]);
|
||||
}
|
||||
|
||||
// 按秩归并
|
||||
void Union(int x1,int x2){
|
||||
x1 = Find(x1);
|
||||
x2 = Find(x2);
|
||||
if(parent[x1] < parent[x2]){
|
||||
parent[x1] += parent[x2];
|
||||
parent[x2] = x1;
|
||||
}else{
|
||||
parent[x2] += parent[x1];
|
||||
parent[x1] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
void Kruskal(){
|
||||
while(MST.size()!=M-1 && !q.empty()){
|
||||
Node E = q.top(); // 最小堆,出队权重最小的
|
||||
q.pop();
|
||||
if(Find(E.v1) != Find(E.v2)){ // 判断是否属于同一集合
|
||||
sum += E.weight;
|
||||
Union(E.v1,E.v2); // 并
|
||||
MST.push_back(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
build();
|
||||
Kruskal();
|
||||
// 图连通
|
||||
if(MST.size()==N-1)
|
||||
cout<<sum;
|
||||
else
|
||||
cout<<-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BIN
编程作业/24.公路村村通.exe
Normal file
BIN
编程作业/24.公路村村通.exe
Normal file
Binary file not shown.
68
编程作业/25.How Long Does It Take.cpp
Normal file
68
编程作业/25.How Long Does It Take.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include<iostream>
|
||||
#include<queue>
|
||||
#include <algorithm>
|
||||
#define MaxVertex 105
|
||||
#define INF -100000
|
||||
typedef int Vertex;
|
||||
using namespace std;
|
||||
int N; // 点
|
||||
int M; // 边
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int Earliest[MaxVertex]; // 时间
|
||||
int Indegree[MaxVertex]; // 入度
|
||||
|
||||
// 初始化图
|
||||
void build(){
|
||||
Vertex v1,v2,w;
|
||||
cin>>N>>M;
|
||||
for(Vertex i=0;i<N;i++){
|
||||
for(Vertex j=0;j<N;j++)
|
||||
G[i][j] = INF;
|
||||
}
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w; // 有向图
|
||||
Indegree[v2]++; // 入度+1
|
||||
}
|
||||
}
|
||||
|
||||
void TopSort(){
|
||||
int cnt = 0;
|
||||
queue<Vertex> q;
|
||||
// 入度为0顶点入队
|
||||
for(Vertex i=0;i<N;i++)
|
||||
if(!Indegree[i]){
|
||||
q.push(i);
|
||||
Earliest[i] = 0;
|
||||
}
|
||||
while(!q.empty()){
|
||||
Vertex v = q.front();
|
||||
q.pop();
|
||||
cnt++;
|
||||
for(Vertex w=0;w<N;w++)
|
||||
if(G[v][w]!=INF){
|
||||
if(Earliest[w] < Earliest[v]+G[v][w]) //如果周围有时间更长,更新时间
|
||||
Earliest[w] = max(Earliest[w],Earliest[v]+G[v][w]);
|
||||
if(--Indegree[w]==0)
|
||||
q.push(w);
|
||||
}
|
||||
}
|
||||
if(cnt!=N)
|
||||
cout<<"Impossible";
|
||||
else{
|
||||
// 也许不止一个终点
|
||||
int max = 0;
|
||||
for(Vertex i=0;i<N;i++)
|
||||
if(max < Earliest[i])
|
||||
max = Earliest[i];
|
||||
cout<<max;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(){
|
||||
build();
|
||||
TopSort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
编程作业/25.How Long Does It Take.exe
Normal file
BIN
编程作业/25.How Long Does It Take.exe
Normal file
Binary file not shown.
83
编程作业/26.关键活动.cpp
Normal file
83
编程作业/26.关键活动.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include<iostream>
|
||||
#include<queue>
|
||||
#include <algorithm>
|
||||
#define MaxVertex 105
|
||||
#define INF 100000
|
||||
typedef int Vertex;
|
||||
using namespace std;
|
||||
int N; // 点
|
||||
int M; // 边
|
||||
int G[MaxVertex][MaxVertex];
|
||||
int Earliest[MaxVertex]; // 最早完成时间
|
||||
int latest[MaxVertex]; // 最晚完成时间
|
||||
int Indegree[MaxVertex]; // 入度
|
||||
int Outdegree[MaxVertex]; // 出度
|
||||
int Max; // 最长时间
|
||||
|
||||
// 初始化图
|
||||
void build(){
|
||||
Vertex v1,v2,w;
|
||||
cin>>N>>M;
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
for(Vertex j=1;j<=N;j++)
|
||||
G[i][j] = INF;
|
||||
for(int i=0;i<M;i++){
|
||||
cin>>v1>>v2>>w;
|
||||
G[v1][v2] = w; // 有向图
|
||||
Indegree[v2]++; // 入度+1
|
||||
Outdegree[v1]++; // 出度+1
|
||||
}
|
||||
}
|
||||
|
||||
// 倒推得到活动最晚完成时间
|
||||
void GetLastest(){
|
||||
|
||||
}
|
||||
|
||||
// 拓扑排序,找到完成项目最短时间
|
||||
bool TopSort(){
|
||||
int cnt = 0;
|
||||
queue<Vertex> q;
|
||||
// 入度为0顶点入队
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
if(!Indegree[i]){
|
||||
q.push(i);
|
||||
Earliest[i] = 0;
|
||||
}
|
||||
while(!q.empty()){
|
||||
Vertex v = q.front();
|
||||
q.pop();
|
||||
cnt++;
|
||||
for(Vertex w=1;w<=N;w++)
|
||||
if(G[v][w]!=INF){
|
||||
if(Earliest[w] < Earliest[v]+G[v][w]) //如果周围有时间更长,更新时间
|
||||
Earliest[w] = max(Earliest[w],Earliest[v]+G[v][w]);
|
||||
if(--Indegree[w]==0)
|
||||
q.push(w);
|
||||
}
|
||||
}
|
||||
if(cnt!=N)
|
||||
return false;
|
||||
else{
|
||||
// 也许不止一个终点
|
||||
Max = 0;
|
||||
for(Vertex i=1;i<=N;i++)
|
||||
if(Max < Earliest[i])
|
||||
Max = Earliest[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(){
|
||||
build();
|
||||
if(!TopSort())
|
||||
cout<<0;
|
||||
else{
|
||||
cout<<Max<<endl;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BIN
编程作业/26.关键活动.exe
Normal file
BIN
编程作业/26.关键活动.exe
Normal file
Binary file not shown.
270
编程作业/27.排序.cpp
Normal file
270
编程作业/27.排序.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
#include<queue>
|
||||
using namespace std;
|
||||
|
||||
// 冒泡排序
|
||||
void Bubble_sort(long A[],int N){
|
||||
for(int i=0;i<N-1;i++){ // N-1次冒泡
|
||||
bool flag = false; // 验证是否交互过
|
||||
for(int j=0;j<N-i-1;j++){
|
||||
if(A[j+1] < A[j]){
|
||||
flag = true;
|
||||
swap(A[j],A[j+1]);
|
||||
}
|
||||
}
|
||||
// 已经有序
|
||||
if(!flag)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 插入排序
|
||||
void Insertion_sort(long A[],int N){
|
||||
for(int i=1;i<N;i++){ // 第一个已经成序
|
||||
long tmp = A[i];
|
||||
int j=i;
|
||||
for(;tmp<A[j-1] && j>0;j--)
|
||||
A[j] = A[j-1];
|
||||
A[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// 原始希尔排序
|
||||
void shell_sort(long A[],int N){
|
||||
for(int D=N/2;D>0;D/=2){
|
||||
for(int p=D;p<N;p++){
|
||||
long tmp = A[p];
|
||||
int k=p;
|
||||
for(;k>=D && tmp<A[k-D] ;k-=D) // j>=D 在前,因为也许 A[j-D]已经越界
|
||||
A[k] = A[k-D];
|
||||
A[k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hibbard增量序列希尔排序
|
||||
void Hibbard_shell_sort(long A[],int N){
|
||||
int add[]={32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0};
|
||||
int i=0;
|
||||
for(int D=add[i];D>0;D=add[++i]){
|
||||
for(int p=D;p<N;p++){
|
||||
long tmp = A[p];
|
||||
int k=p;
|
||||
for(;k>=D && tmp<A[k-D] ;k-=D) // j>=D 在前,因为也许 A[j-D]已经越界
|
||||
A[k] = A[k-D];
|
||||
A[k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sedgewick增量序列哈希排序
|
||||
void Sedgewick_shell_sort(long A[],int N){
|
||||
int add[]= {587521,260609,146305,64769,36289,16001,8929,3905,2161,929,505,209,109,41,19,5,1,0};
|
||||
int i=0;
|
||||
for(int D=add[i];D>0;D=add[++i]){
|
||||
for(int p=D;p<N;p++){
|
||||
long tmp = A[p];
|
||||
int k = p;
|
||||
for(;k>=D && tmp<A[k-D];k-=D)
|
||||
A[k] = A[k-D];
|
||||
A[k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************堆排序开始***************/
|
||||
|
||||
// 调整成最大堆
|
||||
void PrecDown(long A[],int i,int N){
|
||||
int parent,child;
|
||||
long tmp = A[i];
|
||||
// 从 0 开始存,所以关系有变化
|
||||
for(parent = i;parent*2+1<N;parent = child){
|
||||
child = parent*2+1;
|
||||
if((child!=N-1) && (A[child] < A[child+1]))
|
||||
child++;
|
||||
if(A[child] <= tmp)
|
||||
break;
|
||||
else
|
||||
A[parent] = A[child];
|
||||
}
|
||||
A[parent] = tmp;
|
||||
}
|
||||
|
||||
// 堆排序
|
||||
void Heap_sort(long A[],int N){
|
||||
// 先调整成最大堆
|
||||
for(int i=N/2;i>=0;i--)
|
||||
PrecDown(A,i,N);
|
||||
for(int i=N-1;i>0;i--){
|
||||
swap(A[0],A[i]); // 每次把当前最大堆根元素选择出来
|
||||
PrecDown(A,0,i); // 再次调整最大堆
|
||||
}
|
||||
}
|
||||
|
||||
/***************堆排序结束***************/
|
||||
|
||||
/***************stl堆排序开始***************/
|
||||
priority_queue<long,vector<long>,less<long> > q; // 定义一个最大堆
|
||||
|
||||
void STL_Heap_sort(long A[],int N){
|
||||
// 数据读入最大堆
|
||||
for(int i=0;i<N;i++)
|
||||
q.push(A[i]);
|
||||
// 依次出队
|
||||
for(int i=N-1;i>=0;i--){
|
||||
A[i] = q.top();
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
/***************stl堆排序结束***************/
|
||||
|
||||
/***************递归归并排序开始***************/
|
||||
/*
|
||||
// 归并实现
|
||||
void Merge(long A[],long tmpA[],int L,int R,int RightEnd){
|
||||
// L = 左边元素开始位置 ,R = 右边元素开始位置 ,RightEnd = 右边结束终点位置
|
||||
int NumSize = RightEnd-L+1; // 元素个数
|
||||
int LeftEnd = R-1; // 左边元素终点位置
|
||||
int tmp = L; // tmp 数组开始位置
|
||||
while( L <= LeftEnd && R <= RightEnd ){
|
||||
if(A[L] <= A[R]) // 从小到大排序,选小的
|
||||
tmpA[tmp++] = A[L++];
|
||||
else
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
// 也许左没走完
|
||||
while( L <= LeftEnd )
|
||||
tmpA[tmp++] = A[L++];
|
||||
// 也许右边没走完
|
||||
while( R <= RightEnd)
|
||||
tmpA[tmp++] = A[R++];
|
||||
// 再导回 A ,tmp此时已经越界,所以要先减再用
|
||||
for(int i=0;i<NumSize;i++)
|
||||
A[RightEnd--] = tmpA[--tmp];
|
||||
}
|
||||
|
||||
// 分治
|
||||
void Msort(long A[],long tmpA[],int L,int RightEnd){
|
||||
if(L < RightEnd){
|
||||
int center = ( L + RightEnd )/2;
|
||||
Msort(A,tmpA,L,center);
|
||||
Msort(A,tmpA,center+1,RightEnd);
|
||||
Merge(A,tmpA,L,center+1,RightEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void Merge_sort(long A[],int N){
|
||||
long tmpA[N];
|
||||
Msort(A,tmpA,0,N-1);
|
||||
}
|
||||
*/
|
||||
/***************递归归并排序结束***************/
|
||||
|
||||
/***************非递归归并排序开始***************/
|
||||
// 归并实现 ,最后不把元素倒回A
|
||||
void Merge1(long A[],long tmpA[],int L,int R,int RightEnd){
|
||||
// L = 左边元素开始位置 ,R = 右边元素开始位置 ,RightEnd = 右边结束终点位置
|
||||
int NumSize = RightEnd-L+1; // 元素个数
|
||||
int LeftEnd = R-1; // 左边元素终点位置
|
||||
int tmp = L; // tmp 数组开始位置
|
||||
while( L <= LeftEnd && R <= RightEnd ){
|
||||
if(A[L] <= A[R]) // 从小到大排序,选小的
|
||||
tmpA[tmp++] = A[L++];
|
||||
else
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
// 也许左没走完
|
||||
while( L <= LeftEnd )
|
||||
tmpA[tmp++] = A[L++];
|
||||
// 也许右边没走完
|
||||
while( R <= RightEnd)
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
|
||||
// 一趟归并
|
||||
void Merge_pass(long A[],long tmpA[],int N,int length){
|
||||
int i;
|
||||
// 每 2*length 一个单元归并
|
||||
for(i=0;i<N-2*length;i+=2*length)
|
||||
Merge1(A,tmpA,i,i+length,i+2*length-1);
|
||||
// 处理剩余不足一个单元的值
|
||||
if(i+length < N) // 剩下两个子列,左边够,右边不够
|
||||
Merge1(A,tmpA,i,i+length,N-1);
|
||||
else // 剩下一个子列,左边都不够
|
||||
for(int j=i;j<N;j++)
|
||||
tmpA[j] = A[j];
|
||||
}
|
||||
|
||||
|
||||
void Merge_sort(long A[],int N){
|
||||
int length = 1;
|
||||
long tmpA[N];
|
||||
// 保证每次两趟归并,最终结果一定存在 A中
|
||||
while(length < N){
|
||||
Merge_pass(A,tmpA,N,length);
|
||||
length *=2;
|
||||
Merge_pass(tmpA,A,N,length);
|
||||
length *=2;
|
||||
}
|
||||
}
|
||||
|
||||
/***************非递归归并排序结束***************/
|
||||
|
||||
/*********************快速排序开始*******************************************/
|
||||
// 选主元
|
||||
long getPivot(long A[],int L,int R){
|
||||
int center = (L+R)/2;
|
||||
if(A[R] < A[center])
|
||||
swap(A[R],A[center]);
|
||||
if(A[R] < A[L])
|
||||
swap(A[R],A[L]);
|
||||
if(A[center] < A[L])
|
||||
swap(A[center],A[L]);
|
||||
swap(A[center],A[R-1]);
|
||||
return A[R-1];
|
||||
}
|
||||
|
||||
void QucikSort(long A[],int Left,int Right){
|
||||
int cutoff = 50;
|
||||
if( cutoff <= Right - Left ){ // 如果规模大用快排
|
||||
int pivot = getPivot(A,Left,Right);
|
||||
int i = Left;
|
||||
int j = Right-1;
|
||||
for(;;){
|
||||
// 从前往后找比 pivot 小的
|
||||
while(A[++i] < pivot);
|
||||
// 从后往前找比 pivot 大的
|
||||
while(A[--j] > pivot);
|
||||
if(j <= i)
|
||||
break;
|
||||
swap(A[i],A[j]);
|
||||
}
|
||||
// 将主元放在合适位置
|
||||
swap(A[i],A[Right-1]);
|
||||
QucikSort(A,Left,i-1);
|
||||
QucikSort(A,i+1,Right);
|
||||
}else // 否则用插入排序
|
||||
Insertion_sort(A+Left,Right-Left+1);
|
||||
}
|
||||
|
||||
void Quick_sort(long A[],int N){
|
||||
QucikSort(A,0,N-1);
|
||||
}
|
||||
|
||||
/*********************快速排序结束**********************************/
|
||||
|
||||
int main(){
|
||||
int N;
|
||||
cin>>N;
|
||||
long A[N];
|
||||
for(int i=0;i<N;i++)
|
||||
cin>>A[i];
|
||||
Quick_sort(A,N);
|
||||
for(int i=0;i<N;i++){
|
||||
if(i)
|
||||
cout<<" ";
|
||||
cout<<A[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/27.排序.exe
Normal file
BIN
编程作业/27.排序.exe
Normal file
Binary file not shown.
117
编程作业/28.Insert or Merge.cpp
Normal file
117
编程作业/28.Insert or Merge.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
bool judge(int A[],int B[],int N){
|
||||
for(int i=0;i<N;i++)
|
||||
if(A[i]!=B[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 插入排序
|
||||
bool Insertion_Sort(int A[],int B[],int N){
|
||||
for(int P=1;P<N;P++){
|
||||
int tmp = A[P];
|
||||
int j = P;
|
||||
for(;j>0 && tmp < A[j-1];j--)
|
||||
A[j] = A[j-1];
|
||||
A[j] = tmp;
|
||||
if(judge(A,B,N)){ // 如果相等了,再做一轮
|
||||
P++;
|
||||
int tmp = A[P];
|
||||
int j = P;
|
||||
for(;j>0 && tmp < A[j-1];j--)
|
||||
A[j] = A[j-1];
|
||||
A[j] = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Merge(int A[],int tmpA[],int L,int R,int RightEnd){
|
||||
// L = 左边起始位置,R = 右边起始位置,RightEnd = 右边终点位置
|
||||
int NumSize = RightEnd-L+1; // 排序个数
|
||||
int LeftEnd = R-1; // 左边终止位置
|
||||
int tmp = L;
|
||||
// 排序
|
||||
while(L <= LeftEnd && R <= RightEnd){
|
||||
if(A[L] <= A[R])
|
||||
tmpA[tmp++] = A[L++];
|
||||
else
|
||||
tmpA[tmp++] = A[R++];
|
||||
}
|
||||
// 如果左边有剩
|
||||
while(L <= LeftEnd)
|
||||
tmpA[tmp++] = A[L++];
|
||||
// 如果右边有剩
|
||||
while(R <= RightEnd)
|
||||
tmpA[tmp++] = A[R++];
|
||||
// 导回 A 数组
|
||||
for(int i=0;i<NumSize;i++)
|
||||
A[RightEnd--] = tmpA[--tmp];
|
||||
}
|
||||
|
||||
void Merge_pass(int A[],int tmpA[],int N,int length){
|
||||
int i;
|
||||
// 每次 2*length 为一组排序单元
|
||||
for(i=0;i<=N-2*length;i+=2*length)
|
||||
Merge(A,tmpA,i,i+length,i+length*2-1);
|
||||
// 处理剩下的不够一组的排序单元
|
||||
if(i+length < N) // 如果左边够了,但是右边不齐,再次进入排序
|
||||
Merge(A,tmpA,i,i+length,N-1);
|
||||
else // 如果左边都不够,直接导给 tmpA
|
||||
for(int j=i;j<N;j++)
|
||||
tmpA[j] = A[j];
|
||||
}
|
||||
|
||||
// 归并排序
|
||||
bool Merge_Sort(int A[],int B[],int N){
|
||||
int tmpA[N];
|
||||
int length = 1;
|
||||
while(length < N){
|
||||
Merge_pass(A,tmpA,N,length); // 一趟归并
|
||||
length *=2;
|
||||
if(judge(A,B,N)){ // 如果相等了,再做一轮
|
||||
Merge_pass(A,tmpA,N,length);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 输出
|
||||
void output(int A[],int N){
|
||||
for(int i=0;i<N;i++){
|
||||
if(i)
|
||||
cout<<" ";
|
||||
cout<<A[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
int N;
|
||||
cin>>N;
|
||||
int A[N],tmpA[N];
|
||||
for(int i=0;i<N;i++){
|
||||
cin>>A[i];
|
||||
tmpA[i] = A[i];
|
||||
}
|
||||
int B[N];
|
||||
for(int i=0;i<N;i++)
|
||||
cin>>B[i];
|
||||
// 用 tmpA 数组做归并排序,判断是否是归并排序
|
||||
if(!Merge_Sort(tmpA,B,N)){
|
||||
cout<<"Merge Sort"<<endl;
|
||||
output(tmpA,N);
|
||||
return 0;
|
||||
}
|
||||
// 用 A 数组做插入排序,判断是否是插入排序
|
||||
if(!Insertion_Sort(A,B,N)){
|
||||
cout<<"Insertion Sort"<<endl;
|
||||
output(A,N);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/28.Insert or Merge.exe
Normal file
BIN
编程作业/28.Insert or Merge.exe
Normal file
Binary file not shown.
96
编程作业/29.Insertion or Heap Sort.cpp
Normal file
96
编程作业/29.Insertion or Heap Sort.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
using namespace std;
|
||||
void output(int A[],int N);
|
||||
|
||||
// 判断是否相等
|
||||
bool judge(int A[],int B[],int N){
|
||||
for(int i=0;i<N;i++)
|
||||
if(A[i]!=B[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 插入排序
|
||||
bool Insertion_Sort(int A[],int B[],int N){
|
||||
for(int p=1;p<N;p++){
|
||||
int tmp = A[p];
|
||||
int k = p;
|
||||
for(;k>0 && tmp < A[k-1];k--)
|
||||
A[k] = A[k-1];
|
||||
A[k] = tmp;
|
||||
if(judge(A,B,N)){// 如果相等,多做一轮
|
||||
p++;
|
||||
int tmp = A[p];
|
||||
int k = p;
|
||||
for(;k>0 && tmp < A[k-1];k--)
|
||||
A[k] = A[k-1];
|
||||
A[k] = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrecDown(int A[],int i,int N){
|
||||
int tmp = A[i]; // 取得当前"根"
|
||||
int parent,child;
|
||||
for(parent=i;parent*2+1<N;parent = child){
|
||||
child = 2*parent +1;
|
||||
if((child!=N-1) && (A[child] < A[child+1]))
|
||||
child++;
|
||||
if(A[child] <= tmp)
|
||||
break;
|
||||
A[parent] = A[child];
|
||||
}
|
||||
A[parent] = tmp;
|
||||
}
|
||||
|
||||
// 堆排序
|
||||
bool Heap_Sort(int A[],int B[],int N){
|
||||
for(int i=N/2;i>=0;i--)
|
||||
PrecDown(A,i,N);
|
||||
for(int i=N-1;i>0;i--){
|
||||
swap(A[0],A[i]);
|
||||
PrecDown(A,0,i);
|
||||
if(judge(A,B,N)){ // 如果相等,多做一轮
|
||||
swap(A[0],A[--i]);
|
||||
PrecDown(A,0,i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 输出
|
||||
void output(int A[],int N){
|
||||
for(int i=0;i<N;i++){
|
||||
if(i)
|
||||
cout<<" ";
|
||||
cout<<A[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
int N;
|
||||
cin>>N;
|
||||
int A[N],tmpA[N];
|
||||
for(int i=0;i<N;i++){
|
||||
cin>>A[i];
|
||||
tmpA[i] = A[i];
|
||||
}
|
||||
int B[N];
|
||||
for(int i=0;i<N;i++)
|
||||
cin>>B[i];
|
||||
if(!Heap_Sort(tmpA,B,N)){ // 如果是堆排序
|
||||
cout<<"Heap Sort"<<endl;
|
||||
output(tmpA,N);
|
||||
return 0;
|
||||
}
|
||||
if(!Insertion_Sort(A,B,N)){ // 如果是插入排序
|
||||
cout<<"Insertion Sort"<<endl;
|
||||
output(A,N);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/29.Insertion or Heap Sort.exe
Normal file
BIN
编程作业/29.Insertion or Heap Sort.exe
Normal file
Binary file not shown.
45
编程作业/3.二分查找.cpp
Normal file
45
编程作业/3.二分查找.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAXSIZE 10
|
||||
#define NotFound 0
|
||||
typedef int ElementType;
|
||||
|
||||
typedef int Position;
|
||||
typedef struct LNode *List;
|
||||
struct LNode {
|
||||
ElementType Data[MAXSIZE];
|
||||
Position Last; /* 保存线性表中最后一个元素的位置 */
|
||||
};
|
||||
|
||||
Position BinarySearch( List L, ElementType X );
|
||||
|
||||
int main()
|
||||
{
|
||||
List L;
|
||||
ElementType X;
|
||||
Position P;
|
||||
|
||||
L->Data = int[]{1,3,5};
|
||||
L->Last = 3;
|
||||
scanf("%d", &X);
|
||||
P = BinarySearch( L, X );
|
||||
printf("%d\n", P);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Position BinarySearch( List L, ElementType X ){
|
||||
ElementType left = 1;
|
||||
ElementType right = L->Last;
|
||||
while(left<right){
|
||||
ElementType center = (left+right)/2; //先找中间值
|
||||
if(L->Data[center] < X){ //比中间值大,X 在右半边
|
||||
left = center+1;
|
||||
}else if(X < L->Data[center]){ //比中间值小,X 在左半边
|
||||
right = center-1;
|
||||
}else //找到了,直接返回
|
||||
return center;
|
||||
}
|
||||
return NotFound;
|
||||
}
|
||||
23
编程作业/30.统计工龄.cpp
Normal file
23
编程作业/30.统计工龄.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
|
||||
void bucket_sort(int A[],int N){
|
||||
int count[55];
|
||||
for(int i=0;i<55;i++)
|
||||
count[i] = 0;
|
||||
for(int i=0;i<N;i++)
|
||||
count[A[i]]++;
|
||||
for(int i=0;i<55;i++)
|
||||
if(count[i])
|
||||
cout<<i<<":"<<count[i]<<endl;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int N;
|
||||
cin>>N;
|
||||
int A[N];
|
||||
for(int i=0;i<N;i++)
|
||||
cin>>A[i];
|
||||
bucket_sort(A,N);
|
||||
return 0;
|
||||
}
|
||||
BIN
编程作业/30.统计工龄.exe
Normal file
BIN
编程作业/30.统计工龄.exe
Normal file
Binary file not shown.
95
编程作业/31.PAT Judge.cpp
Normal file
95
编程作业/31.PAT Judge.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include<cstdio>
|
||||
#include<algorithm>
|
||||
#include<vector>
|
||||
|
||||
const int INIT = -2; // 初始化
|
||||
const int NOPASS = -1; // 未通过编译
|
||||
const int MAXID = 10005; //最大ID
|
||||
using namespace std;
|
||||
|
||||
struct info{
|
||||
int id; // id号
|
||||
int ques[6]; // 每道题得分
|
||||
int sum; // 总分
|
||||
int solved; // 答对题数
|
||||
};
|
||||
|
||||
// 定义sort 的排序规则
|
||||
bool cmp(info a,info b){
|
||||
if(a.sum != b.sum)
|
||||
return a.sum>b.sum;
|
||||
if(a.solved != b.solved)
|
||||
return a.solved > b.solved;
|
||||
return a.id < b.id;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
int N; // 使用者总数
|
||||
int K; // 问题总数
|
||||
int M; // 提交总数
|
||||
scanf("%d %d %d",&N,&K,&M);
|
||||
vector<info> user(N+1); // 使用者信息
|
||||
int Full[K+1]; // 记录问题总分 ,a[i] 表示第i道题的分数
|
||||
for(int i=1;i<=K;i++)
|
||||
scanf("%d",&Full[i]);
|
||||
// 初始化信息
|
||||
for(int i=1;i<N+1;i++){
|
||||
user[i].id = MAXID; // 初始化成最大
|
||||
user[i].sum = 0;
|
||||
user[i].solved = 0;
|
||||
for(int j=1;j<K+1;j++)
|
||||
user[i].ques[j] = INIT;
|
||||
}
|
||||
int use; // 玩家编号
|
||||
int question; // 问题编号
|
||||
int score; // 得分
|
||||
int listSum = 0; // 应该被输出总数
|
||||
for(int i=0;i<M;i++){
|
||||
scanf("%d %d %d",&use,&question,&score);
|
||||
// 只要通过编译,该玩家就能被显示
|
||||
if(score >= 0 && user[use].id == MAXID){
|
||||
listSum++;
|
||||
user[use].id = use;
|
||||
}
|
||||
// 分数有更大更新成更大
|
||||
if(user[use].ques[question] < score){
|
||||
user[use].ques[question] = score;
|
||||
}
|
||||
}
|
||||
for(int i=1;i<N+1;i++)
|
||||
for(int j=1;j<K+1;j++){
|
||||
// 计算完全正确解题数
|
||||
if(user[i].ques[j] == Full[j])
|
||||
user[i].solved++;
|
||||
// 计算总分
|
||||
if(user[i].ques[j] != NOPASS && user[i].ques[j] != INIT)
|
||||
user[i].sum += user[i].ques[j];
|
||||
}
|
||||
|
||||
sort(user.begin()+1,user.end(),cmp);
|
||||
|
||||
int preSum = user[1].sum;
|
||||
int preNum = 1;
|
||||
|
||||
for(int i=1;i<=listSum;i++){
|
||||
// 如果和上次分数不同,更新排名
|
||||
if(preSum != user[i].sum){
|
||||
preNum = i;
|
||||
preSum = user[i].sum;
|
||||
}
|
||||
printf("%d ",preNum);
|
||||
printf("%05d %d",user[i].id,user[i].sum);
|
||||
for(int j=1;j<K+1;j++){
|
||||
// 依旧初始化状态
|
||||
if(user[i].ques[j] == INIT)
|
||||
printf(" -");
|
||||
else if(user[i].ques[j] == NOPASS)
|
||||
printf(" 0");
|
||||
else
|
||||
printf(" %d",user[i].ques[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user