Initial commit

This commit is contained in:
callmePicacho
2019-05-08 19:49:54 +08:00
commit 22c59de0c3
125 changed files with 6631 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

1
README.md Normal file
View File

@@ -0,0 +1 @@
# Data-Structres

View 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);
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}
*/

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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

Binary file not shown.

View 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;
}

Binary file not shown.

66
上课Demo/20.Floyd.cpp Normal file
View 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

Binary file not shown.

91
上课Demo/21.Prim.cpp Normal file
View 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

Binary file not shown.

98
上课Demo/22.Kruskal.cpp Normal file
View 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

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

105
上课Demo/25.KMP算法.cpp Normal file
View 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

Binary file not shown.

View 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->Nextp 指针指向 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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);
}
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

270
编程作业/27.排序.cpp Normal file
View 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

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

Binary file not shown.

View 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;
}

View 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;
}

Binary file not shown.

View 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