数据结构实验代码示例

今天在整理电脑的时候发现上个学期学的数据结构还没有整理成博客。今天整理整理。

顺序表

在这里插入图片描述
代码示例:

#include<bits/stdc++.h>
#define MAXSIZE 1024
using namespace std;
typedef int elemtype;
typedef struct {
	elemtype data[MAXSIZE];
	int last;
}SequenList;
bool cmp(int a,int b)
{
	return (b<a); 
} 
SequenList* init()
{
	SequenList* L;
	L=(SequenList*)malloc(sizeof(SequenList));
	L->last=-1;
	return L;
}
SequenList* creat(SequenList* L)
{
	int x;
	printf("请输入要存储的数据(以0为结束):");
	scanf("%d",&x);
	while(1)
	{
		L->last++;
		L->data[L->last]=x;
		scanf("%d",&x);
		if(x==0)
			return L;
	} 
}
void Print(SequenList* L)
{
	int i;
	for(i=0;i<=L->last;i++)
		printf("%d ",L->data[i]);
	printf("\n");
}
void mumen()
{
	printf("1.删除\n");
	printf("2.插入\n");
	printf("3.查找\n");
	printf("4.排序\n");
	printf("5.销毁\n");
}
int find(SequenList* L,int x)
{
	int i,j;
	for(i=0;i<=L->last;i++)	
		if(L->data[i]==x)
			return i;
	return -1;
}
void delet(SequenList* L,int x)
{
	int i,j;
	for(i=0;i<=L->last&&L->data[i]!=x;i++);	
	for(j=i+1;j<=L->last;j++)
		L->data[j-1]=L->data[j];
	L->last--;
}
void insert(SequenList* L,int index)
{
	int data,i;
	if(index<1||index>L->last+2)
	{
		printf("位置错误!\n");
		return ;
	}
	printf("请输入要插入的数据:");
	scanf("%d",&data);
	for(i=L->last+1;i>index-1;i--)
	{
		L->data[i]=L->data[i-1];
	}
	L->data[i]=data;
	L->last++;
	printf("插入成功!\n");
}
void data_sort(SequenList* L)
{
	int x;
	printf("1.升序排序\n");
	printf("2.降序排序\n");
	scanf("%d",&x);
	if(x==1)
		sort(L->data,L->data+L->last+1);
	if(x==2)
		sort(L->data,L->data+L->last+1,cmp);
}
void destroy(SequenList* L)
{
	free(L);
}
int main()
{
	SequenList* L;
	L=init();
	L=creat(L);
	Print(L);
	
	int n,x,f,index,f1=0;
	while(1)
	{
		mumen();
		scanf("%d",&n);
		switch(n)
		{
			case 1:
				printf("请输入要删除的数据:");
				scanf("%d",&x);
				f=find(L,x);
				if(f==-1)
					printf("未找到该数\n");
				else
				{
					delet(L,x); 
					printf("删除成功!\n");
					Print(L);
				}
				break;
			case 2:
				printf("请选择要插入的位置:");
				scanf("%d",&index);
				insert(L,index); 
				
				Print(L);
				break;
			case 3:
				printf("请输入要查询的数据:");
				scanf("%d",&x);
				f=find(L,x);
				if(f==-1)
					printf("没有该数\n");
				else
					printf("存在该数,在第%d位\n",f+1);
				Print(L);
				break;				
			case 4:
				data_sort(L);
				Print(L); 
				break;
			case 5:
				destroy(L);
				printf("顺序表已销毁\n");
				f1=1;
		}	
		if(f1==1)
			break;
	}
}

迷宫问题(栈)

在这里插入图片描述
这个题就是个dfs题,但是思想是栈,最后打印路径用到了栈。程序结尾附样例。

#include<bits/stdc++.h>
using namespace std;
struct dis{
    int x,y;
};
stack<struct dis> s,s1;
int dd[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int vis[11][11];
int mp[11][11];
int n,m,f=0;
struct dis p;
void Migong(int x,int y)
{
    int x1,y1;
    struct dis t;	
    if(x==n-2&&y==m-2)
    {
    	f=1;
        while(!s.empty())
        {
            s1.push(s.top());
            s.pop();
        }
        while(!s1.empty())
        {
            t=s1.top();
            s1.pop();
            printf("(%d,%d)\n",t.x,t.y);
        }
        return ;
    }            
    for(int i=0;i<4;i++)
    {
        x1=x+dd[i][0];
        y1=y+dd[i][1];
        if(mp[x1][y1]==0&&vis[x1][y1]==0)
        {
            vis[x1][y1]=1;
            p.x=x1;
            p.y=y1;
            s.push(p);
            Migong(x1,y1);
            if(!s.empty())
            	s.pop();
        }
    }

}
int main()
{
	int i;   
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++)
        for(int j=0;j<m;j++)
            scanf("%d",&mp[i][j]);
    p.x=1,p.y=1;
    vis[1][1]=1;
    s.push(p);
    Migong(1,1);
    if(f==0)
    	printf("此迷宫不通\n");
}
/*
正常: 
1 1 1 1 1 1 1
1 0 0 1 0 0 1
1 0 0 1 0 1 1
1 0 0 0 0 0 1
1 0 1 0 1 0 1
1 0 1 0 1 0 1
1 1 1 1 1 1 1
有岔路: 
1 1 1 1 1 1 1
1 0 0 1 0 0 1
1 0 0 1 0 1 1
1 0 0 0 0 1 1
1 0 1 0 1 0 1
1 0 1 0 0 0 1
1 1 1 1 1 1 1
不通: 
1 1 1 1 1 1 1
1 0 0 1 0 0 1
1 0 0 1 0 1 1
1 0 0 0 0 1 1
1 0 1 0 1 0 1
1 0 1 0 1 0 1
1 1 1 1 1 1 1

*/

表达式求值(栈)

在这里插入图片描述
实验要求链栈,但是感觉并没有必要,就用了数组代替。此程序分为两部分,中缀转后缀和表达式求值。注意表达式的运算规则,负数,小数的运算

#include <bits/stdc++.h>
using namespace std;
stack<char> st;
stack<double> val;
int Judge(char c)
{
	if (c == '+' || c == '-')
		return 1;
	else if (c == '*' || c == '/')
		return 2;
	else if (c == '(')
		return 3;
	else if (c == ')')
		return 4;
	return 0;
}
void cul()
{
	char c;
	c=st.top();
	double a,b;
	if (c == '+')
	{
		a = val.top();
		val.pop();
		b = val.top();
		val.pop();
		val.push(b + a);
	}
	else if (c == '-')
	{
		a = val.top();
		val.pop();
		b = val.top();
		val.pop();
		val.push(b - a);
	}
	else if (c == '*')
	{
		a = val.top();
		val.pop();
		b = val.top();
		val.pop();
		val.push(b * a);
	}
	else if (c == '/')
	{
		a = val.top();
		val.pop();
		b = val.top();
		val.pop();
		val.push(b / a);
	}
}
int ff=0;
int main()
{
	int f1 = 1,n;
	double sum = 0, sum1 = 0, cheng = 0.1;
	int i = 0, f;
	char s[100];
	printf("请输入:\n");
	printf("1.中缀转后缀\n");
	printf("2.表达式求值\n");
	scanf("%d",&n);
	if(n==1)
	{
		printf("请输入表达式:");
		scanf("%s", s);
		while (s[i] != '\0')
		{
			f = Judge(s[i]);
			if (f != 0)
			{
				switch (f)
				{
					case 1:
						if (s[i] == '+' && (i == 0 || (s[i - 1] <= '0' || s[i - 1] >= '9')) && s[i - 1] != ')')
						{
							i++;
							continue;
						}
						else if (s[i] == '-' && (i == 0 || (s[i - 1] <= '0' || s[i - 1] >= '9')))
						{
							ff=1;
							i++;
							continue;
						}
						else if (s[i] == '-' || s[i] == '+')
						{

							while (1)
							{

								if (st.empty() || st.top() == '(')
								{
									st.push(s[i]);
									break;
								}
								else if (st.top() == '+' || st.top() == '-' || st.top() == '*' || st.top() == '/')
								{
									if (f1 == 1)
									{
										f1 = 0;
										printf("%c", st.top());
									}
									else
										printf(" %c", st.top());
									st.pop();
								}
								else
									break;
							} 
						}
						break;
					case 2:
						while (1)
						{
							if (st.empty() || st.top() == '+' || st.top() == '-' || st.top() == '(')
							{
								st.push(s[i]);
								break;
							}
							else if (st.top() == '*' || st.top() == '/')
							{
								if (f1 == 1)
								{
									f1 = 0;
									printf("%c", st.top());
								}
								else
									printf(" %c", st.top());
								st.pop();
							}
							else
								break;
						}
						break;
					case 3:
						st.push(s[i]);
						break;
					case 4:
						while (1)
						{
							if (st.top() == '(')
							{
								st.pop();
								break;
							}
							else
							{
								if (f1 == 1)
								{
									f1 = 0;
									printf("%c", st.top());
								}
								else
									printf(" %c", st.top());
								st.pop();
							}
						}
						break;
				}
			}
			else
			{
				while (s[i] >= '0' && s[i] <= '9')
				{
					sum = sum * 10 + s[i] - '0';
					i++;
				}
				if (s[i] == '.')
				{
					sum1 = 0;
					i++;
					while (s[i] >= '0' && s[i] <= '9')
					{
						sum1 = sum1 + (s[i] - '0') * cheng;
						cheng = cheng * 0.1;
						i++;
					}
				}
				i--;
				if (sum1 != 0)
				{
					if (f1 == 1)
					{
						f1 = 0;
						cout << sum + sum1;
					}
					else
						cout <<" "<< sum + sum1 ;
				}
				else if (f1 == 1)
				{
					f1 = 0;
					printf("%.f", sum);
				}
				else
					printf(" %.f", sum);
				cheng = 0.1;
				sum1 = 0;
				sum = 0;
			}
			i++;
		}
		while (!st.empty())
		{
			if (f1 == 1)
			{
				f1 = 0;
				printf("%c", st.top());
			}
			else
				printf(" %c", st.top());
			st.pop();
		}
	}
	else
	{
		string s1;
		char s2[100];
		int a,b;
		printf("请输入表达式:");
		scanf("%s", s);
		while (s[i] != '\0')
		{
			f = Judge(s[i]);
			if (f != 0)
			{
				switch (f)
				{
					case 1:
						if (s[i] == '+' && (i == 0 || (s[i - 1] <= '0' || s[i - 1] >= '9')) && s[i - 1] != ')')
						{
							i++;
							continue;
						}
						else if (s[i] == '-' && (i == 0 || (s[i - 1] <= '0' || s[i - 1] >= '9')))
						{
							ff=1;
							i++;
							continue;
						}
						else if (s[i] == '-' || s[i] == '+')
						{

							while (1)
							{
								if (st.empty() || st.top() == '(')
								{
									st.push(s[i]);
									break;
								}
								else if (st.top() == '+' || st.top() == '-' || st.top() == '*' || st.top() == '/')
								{
									cul();
									st.pop();
								}
								else
									break;
							} 
						}
						break;
					case 2:
						while (1)
						{
							if (st.empty() || st.top() == '+' || st.top() == '-' || st.top() == '(')
							{
								st.push(s[i]);
								break;
							}
							else if (st.top() == '*' || st.top() == '/')
							{
								cul();
								st.pop();
							}
							else
								break;
						}
						break;
					case 3:
						st.push(s[i]);
						break;
					case 4:
						while (1)
						{
							if (st.top() == '(')
							{
								st.pop();
								break;
							}
							else
							{
								cul();
								st.pop();
							}
						}
						break;
				}
			}
			else
			{
				while (s[i] >= '0' && s[i] <= '9')
				{
					sum = sum * 10 + s[i] - '0';
					i++;
				}
				if (s[i] == '.')
				{
					sum1 = 0;
					i++;
					while (s[i] >= '0' && s[i] <= '9')
					{
						sum1 = sum1 + (s[i] - '0') * cheng;
						cheng = cheng * 0.1;
						i++;
					}
				}
				i--;
					if(ff==1)
						val.push(-(sum+sum1));
					else
						val.push(sum+sum1);
					ff=0;
				cheng = 0.1;
				sum1 = 0;
				sum = 0;
			}
			i++;
		}
		while (!st.empty())
		{
			cul();
			st.pop();
		}
		double ta=0,tb=0;
		ta=val.top();
		val.pop();
		if(!val.empty())
		{
			tb=val.top();
		}
		printf("%lf\n",ta+tb);

	}


}
/*
2+3*(7-4)+8/4
*/

表达式树的构建

这个属于实验外的东西了,老师布置的课余时间的作业,做着玩玩。
老师要求的是自动出题器,用树来表示,主要思想就是叶子节点是运算数,非叶子节点是运算符,这样通过中序遍历就可以得到一个表达式,c语言很难把整棵树形象的表示出来,我用了括号来表示。

#include<bits/stdc++.h>
using namespace std;
typedef struct t
{
	int data;
	struct t *l,*r;
	int h;
} Tree;
Tree* create(int h)
{
	Tree* t;
	int num;
	int c;

	if(h==5)
		return NULL;
	else
	{
		t= (Tree*)malloc(sizeof(Tree));
		if(h==0)
		{
			int magic=rand()%4;
			if(magic==3)	c=-3;
			else if(magic==2)	c=-2;
			else if(magic==1)	c=-1;
			else if(magic==0)	c=-4;
			t->data=c;
		}
		else if(h==4)
		{
			int magic=rand()%100;
			t->data=magic;
		}
		else
		{
			int magic=rand()%5;
			if(magic>3)
			{
				magic=rand()%10;
				printf("%d\n",magic);
				t->data=magic;
				return t;
			}
			if(magic==3)	c=-3;
			else if(magic==2)	c=-2;
			else if(magic==1)	c=-1;
			else if(magic==0)	c=-4;
			t->data=c;
		}
		t->l=create(h+1);
		t->r=create(h+1);
	}
	return t;
}
void Print(Tree* T)
{
	if(T)
	{
		if(T->data>=0)
			printf("%d",T->data);
		else
		{
			printf("(");
			Print(T->l);
			if(T->data==-4)	printf("+");
			if(T->data==-1)	printf("-");
			if(T->data==-2)	printf("*");
			if(T->data==-3)	printf("/");
			Print(T->r);
			printf(")");
		}

	}
}
int main()
{
	srand((unsigned) time(NULL));
	Tree* T;
	T=create(0);
	Print(T);
}

杨辉三角(队列)

在这里插入图片描述
杨辉三角的生成一般是用不着队列的,也许用队列实现就只是单纯的练习一下队列的操作吧,我这次没有用STL的队列,毕竟了解一下底层实现也挺好的。。。
如果想用别的方法生成杨辉三角,请移步我的另一篇博客 杨辉三角形

#include<stdio.h>
#include<memory.h>
#include<stdlib.h> 
#define MAXSIZE 100
typedef struct queue
{
    int data[100];
    int rear,front;
}Queue;
Queue* init()
{
    Queue* q;
    q=(Queue*)malloc(sizeof(Queue));
    memset(q->data,0,sizeof(q->data));
    q->front=q->rear=0;
    return q;
}
void enqueue(Queue *q,int x)
{
    q->data[q->rear]=x;
    q->rear=(q->rear+1)%MAXSIZE;
}
int dequeue(Queue* q)
{
    int x;
    x=q->data[q->front];
    q->front=(q->front+1)%MAXSIZE;
    return x;
}
int getqueue(Queue* q)
{
    return q->data[q->front];
}
int isempty(Queue* q)
{
    if(q->front==q->rear)
        return 1;
    return 0;
}
void PrintTriangle(Queue* q,int n)
{
    int x,t;
    enqueue(q,1);
    for(int i=2;i<=n;i++)
    {
        enqueue(q,1);
        for(int j=1;j<=i-2;j++)
        {
            t=dequeue(q);
            printf("%d ",t);
            x=getqueue(q);
            t=t+x;
            enqueue(q,t);
        }
        x=dequeue(q);
        printf("%d ",x);
        enqueue(q,1);
        printf("\n");
    }
    while(!isempty(q))
    {
        x=dequeue(q);
        printf("%d ",x);
    }
}
int main()
{
	int n;
    Queue* q;
    q=init();
    scanf("%d",&n);
    PrintTriangle(q,n);
}

二叉树

二叉树的递归遍历

在这里插入图片描述
递归遍历没什么好说的

#include <stdio.h>
#include <stdlib.h>
typedef struct tree
{
    int data;
    struct tree *r, *l;
} Tree;
int a[100];
Tree *create()
{
    int x;
    Tree *T;
    scanf("%d", &x);
    if (x == 0)
        return NULL;
    else
    {
        T = (Tree *)malloc(sizeof(Tree));
        T->data = x;
        T->l = create();
        T->r = create();
    }
    return T;
}
void Printpre(Tree *T)
{
    if (T)
    {
        printf("%d ", T->data);
        Printpre(T->l);
        Printpre(T->r);
    }
    return;
}
void Printmid(Tree *T)
{
    if (T)
    {

        Printmid(T->l);
        printf("%d ", T->data);
        Printmid(T->r);
    }
    return;
}
void Printaft(Tree *T)
{
    if (T)
    {

        Printaft(T->l);
        Printaft(T->r);
        printf("%d ", T->data);
    }
    return;
}
int main()
{
    Tree *T;
    printf("请先序输入树节点的值,如没有,则用0代替:");
    T = create();
    printf("先序遍历结果:");
    Printpre(T);
    printf("\n");
    printf("中序遍历结果:");
    Printmid(T);
    printf("\n");
    printf("后序遍历结果:");
    Printaft(T);
}
/*
1 2 4 0 0 5 0 0 3 0 0 

1 2 4 6 0 0 0 5 7 0 0 0 3 0 8 0 0
*/

二叉树非递归遍历

在这里插入图片描述
主要是练习栈的使用,还有队列的层序遍历

#include<bits/stdc++.h>
using namespace std;
typedef struct tree
{
    int data;
    bool flag;
    struct tree *r, *l;
} Tree;
queue<Tree*> q;
int a[100];
Tree *create()
{
    int x;
    Tree *T;
    scanf("%d", &x);
    if (x == 0)
        return NULL;
    else
    {
        T = (Tree *)malloc(sizeof(Tree));
        T->data = x;
        T->l = create();
        T->r = create();
    }
    return T;
}
void InorderTraversal( Tree* BT )
{
	stack<Tree*> S;
	Tree* T;
	T=BT;
	while(T||!S.empty())
	{
		while(T)
		{
			S.push(T);
			T=T->l;
		}
		if(!S.empty())
		{
			T=S.top();
			S.pop(); 
			printf(" %d",T->data);
			T=T->r;
		}
	}
}
void PreorderTraversal( Tree* BT )
{
	stack<Tree*> S;
	Tree* T;
	T=BT;
	while(T||!S.empty())
	{
		while(T)
		{
			printf(" %d",T->data);
			S.push(T);
			T=T->l;
		}
		if(!S.empty())
		{
			T=S.top();
			S.pop(); 
			
			T=T->r;
		}
	}
}
void PostorderTraversal( Tree* BT )
{
	stack<Tree*> S;
	Tree* T=BT;
	Tree* p;
	while(T||!S.empty())
	{
		while(T)
		{
			T->flag=true;
			S.push(T);
			T=T->l;
		}
		while(!S.empty())
		{
			p=S.top();
			if(p->flag==true)
				break;
			T=S.top();
			S.pop();
			printf(" %d",T->data);
			T=NULL;
		}
		if(!S.empty())
		{
			p=S.top();
			p->flag=false;
			T=p->r;
		}
	}
}
void cengPrint(Tree* T)
{
	Tree* T1;
	q.push(T);
	while(!q.empty())
	{
		T1=q.front();
		q.pop();
		printf("%d ",T1->data);
		if(T1->l!=NULL)
			q.push(T1->l);
		if(T1->r!=NULL)
			q.push(T1->r);
	}
}
int main()
{
    Tree *T;
    printf("请先序输入树节点的值,如没有,则用0代替:");
    T = create();
    printf("先序遍历结果:");
    PreorderTraversal(T);
    printf("\n");
    printf("中序遍历结果:");
    InorderTraversal(T);
    printf("\n");
    printf("后序遍历结果:");
    PostorderTraversal(T);
    printf("\n");
    printf("层序遍历结果:");
    cengPrint(T);
    
}
/*
1 2 4 0 0 5 0 0 3 0 0 

1 2 4 6 0 0 0 5 7 0 0 0 3 0 8 0 0
*/

哈夫曼树

在这里插入图片描述

开始是直接写的,没有对文件的操作,但是后来想了想,既然写了,那就带上文件操作吧,这样看起来更完整些

#include<bits/stdc++.h>
#include<windows.h>
#define inf 999999
using namespace std;
char s[10000];
map<char,double> mp;
map<char,string> mp1;
int n;
int m;
struct node
{
	int w;
	char data;
	char *ma;
	int par,l,r;
};
string ll;
string s1;
struct node Tree[1000];
struct node * p;
bool cmp(struct node a,struct node b)
{
	return a.w<b.w;
}
void  GetFZ()
{
	int i;
	gets(s);
	int len=strlen(s);
	for(i=0; i<len; i++)
		mp[s[i]]++;
	map<char,double> ::iterator it;
	for(it=mp.begin(); it!=mp.end(); it++)
		n++;
	m=2*n-1;
	for(p=Tree,i=0,it=mp.begin(); it!=mp.end()&&i<n; it++,p++)
	{
		p->w=it->second;
		p->data=it->first;
		p->par=-1;
		p->l=-1;
		p->r=-1;
	}
	for(; i<m; i++,p++)
	{
		p->w=0;
		p->l=-1;
		p->r=-1;
		p->par=-1;
		p->data=' ';
	}
	int m1,m2,x1,x2,j;
	for(i=n; i<m; i++)
	{
		m1=m2=inf;
		x1=x2=0;
		for(j=0; j<i; j++)
		{
			if(Tree[j].par==-1&&Tree[j].w<m1)
				m2=m1,x2=x1,m1=Tree[j].w,x1=j;
			else if(Tree[j].par==-1&&Tree[j].w<m2)
				m2=Tree[j].w,x2=j;
		}
		Tree[x1].par=i;
		Tree[x2].par=i;
		Tree[i].l=x1;
		Tree[i].r=x2;
		Tree[i].w=m1+m2;
	}
}
void  GetFZ(int x)
{
	int i;
	ifstream in("yuanwenjian.txt");
	if(in) // 有该文件
		getline (in, ll);// line中不包括每行的换行符
	int len=ll.size();
	for(i=0; i<len; i++)
		mp[ll[i]]++;
	map<char,double> ::iterator it;
	for(it=mp.begin(); it!=mp.end(); it++)
		n++;
	m=2*n-1;
	for(p=Tree,i=0,it=mp.begin(); it!=mp.end()&&i<n; it++,p++)
	{
		p->w=it->second;
		p->data=it->first;
		p->par=-1;
		p->l=-1;
		p->r=-1;
	}
	for(; i<m; i++,p++)
	{
		p->w=0;
		p->l=-1;
		p->r=-1;
		p->par=-1;
		p->data=' ';
	}
	int m1,m2,x1,x2,j;
	for(i=n; i<m; i++)
	{
		m1=m2=inf;
		x1=x2=0;
		for(j=0; j<i; j++)
		{
			if(Tree[j].par==-1&&Tree[j].w<m1)
				m2=m1,x2=x1,m1=Tree[j].w,x1=j;
			else if(Tree[j].par==-1&&Tree[j].w<m2)
				m2=Tree[j].w,x2=j;
		}
		Tree[x1].par=i;
		Tree[x2].par=i;
		Tree[i].l=x1;
		Tree[i].r=x2;
		Tree[i].w=m1+m2;
	}
}
void JetTree()
{
	int i,c,f,str;
	struct node Jie[n+1];
	char s1[n+1];
	s1[n-1]='\0';
	for(i=0; i<n; i++)
	{
		str=n-1;
		for(c=i,f=Tree[i].par; f!=-1; c=f,f=Tree[f].par)
			if(Tree[f].l==c) s1[--str]='0';
			else s1[--str]='1';
		Tree[i].ma=(char*)malloc((n-str)*sizeof(char));
		strcpy(Tree[i].ma,&s1[str]);
		mp1[Tree[i].data]=Tree[i].ma;
	}

}
void Jiema()
{
	int i;
	for(i=0;i<m;i++)
		if(Tree[i].par==-1)
			break;
	int pos=i;
	int pos1=pos;
	int k=0;
	while(1)
	{
		if(Tree[pos1].l==-1&&Tree[pos1].r==-1)
		{
			printf("%c",Tree[pos1].data);
			s1+=Tree[pos1].data;
			pos1=pos;
			continue;
		}
		else if(ll[k]=='0')
			pos1=Tree[pos1].l;
		else if(ll[k]=='1')
			pos1=Tree[pos1].r;
		else
			break;
		k++;
	}
	printf("\n");
}
int main()
{
	int ff;
	string ss;

	printf("1. 从文件解码\n2. 压缩到文件\n3. 从文件读入并压缩\n");
	ofstream fout;
	
	while(1)
	{
		scanf("%d",&ff);getchar();
		if(ff==1)
		{
			ifstream in("yasuo.txt");
			if(in) // 有该文件
				getline (in, ll);// line中不包括每行的换行符
//			GetFZ(1);
			Jiema();
		}
		else if(ff==2)
		{
			GetFZ();
			JetTree();
			for(int i=0; i<strlen(s); i++)
			{
				ss+=mp1[s[i]];
			}
			fout.open("yasuo.txt");
			cout<<ss<<endl;
			fout<<ss<<endl;
			fout.close();
			for(int i=0; i<n; i++)
				printf("%c %s\n",Tree[i].data,Tree[i].ma);
			printf("压缩成功!\n"); 
		}
		else if(ff==3)
		{
			GetFZ(1);
			JetTree();
			for(int i=0; i<ll.size(); i++)
				ss+=mp1[ll[i]];
			for(int i=0; i<n; i++)
				printf("%c %s\n",Tree[i].data,Tree[i].ma);
			fout.open("yasuo.txt");
			cout<<ss<<endl;
			fout<<ss<<endl;
			fout.close();
		}
		
	}

}

图论

图的深度优先遍历

在这里插入图片描述
图论最基础就是遍历,深度优先遍历,简称dfs
这个程序是最最简单的dfs板子。

#include<stdio.h>
int mp[100][100];//存储图 
int vis[100];//判断是否便利过,遍历过置成1 
int num,bian;
void dfs(int x)
{
	int i;
	vis[x]=1;//遍历这个顶点,置1 
	printf("%d ",x);//输出这个节点。 
	for(i=0;i<num;i++)//站在这个点上,看其他所有点 
		if(vis[i]==0&&mp[x][i]==1)//如果这个点没有遍历过(vis[i]==0),并且 x 顶点和 i 顶点有边 ,递归进去。 
			dfs(i);
	return ;
}
int main()
{
	int i,x,y;
	scanf("%d%d",&num,&bian);//输入顶点个数,边的个数。 
	for(i=0;i<bian;i++)
	{
		scanf("%d%d",&x,&y);//输入一个边的两个顶点,比如输入3 4,说明顶点3和顶点4之间有边 
		mp[x][y]=mp[y][x]=1;//mp[3][4]=1,就说明3和4之间有边 
	}
	dfs(0);//从顶点0开始遍历。 
}
/*
8 10
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
5 7
6 7
*/

图的广度优先遍历

广度优先遍历简称bfs

#include<stdio.h>
int mp[100][100];
int vis[100];
int num,bian;
void bfs(int x)
{
	int q[1000],rear=0,front=0;//模拟一个队列 
	int i; 
	vis[x]=1;//访问过,置 1 
	q[rear++]=x;//元素入队列 
	while(rear!=front)//当队列中有元素的时候,一直循环。 
	{
		int p=q[front++];//取队头元素 
		printf("%d ",p);
		for(i=0;i<num;i++)//站在这个顶点上看 
		{
			if(vis[i]==0&&mp[p][i]==1)//如果顶点 i 没有访问过,并且 p顶点和 i 顶点有边。则 置 1 ,并 入队 
			{
				vis[i]=1;
				q[rear++]=i;
			}
		}
	}
}
int main()
{
	int i,x,y;
	scanf("%d%d",&num,&bian);
	for(i=0;i<bian;i++)
	{
		scanf("%d%d",&x,&y);;
		mp[x][y]=mp[y][x]=1;
	}
	bfs(0);
}

Prim最小生成树算法

这个也是很基础的最小生成树算法了

#include<bits/stdc++.h>
#define inf 99999
using namespace std;
int mp[100][100];
int dis[100];
int vis[100];
int num;
void prim(int x)
{
	int sum=0,i,j;
	vis[x]=1;
	for(i=0;i<num;i++)
		dis[i]=mp[x][i];
	int u=-1;
	for(i=1;i<num;i++)
	{
		int min=inf;
		for(j=0;j<num;j++)
		{
			
			if(vis[j]==0&&dis[j]<min)
				min=dis[u=j];
		}
		if(u==-1)
			break;
		sum+=min;
		vis[u]=1;
		for(j=0;j<num;j++)
			if(vis[j]==0&&dis[j]>mp[u][j])
				dis[j]=mp[u][j];
	}
	printf("sum = %d",sum);
}
int main()
{
	int bian,i,j,x,y,w;
	scanf("%d%d",&num,&bian);
	for(i=0;i<bian;i++)
		for(j=0;j<bian;j++)
			mp[i][j]=inf;
	for(i=0;i<bian;i++)
	{
		scanf("%d%d%d",&x,&y,&w);
		mp[x][y]=w;
		mp[y][x]=w;
	}
	prim(0);
		
}

/*
7 12
0 1 2
0 2 4
0 3 1
1 3 3
1 4 10
2 3 2
2 5 5
3 5 8
3 6 4
3 4 7
5 6 1
4 6 6
*/

Kruskal最小生成树算法

老师上课讲的是将各边的关系存在一个链表里,维护这个链表,但这种方法太麻烦了。
用并查集就行。

#include<bits/stdc++.h>
using namespace std;
struct Gr{
	int u,v,w;
}G[1000];
int a[1000];
int num;
int bian;
bool cmp(struct Gr a,struct Gr b)
{
	return a.w<b.w;
}
void init()
{
	for(int i=0;i<=num;i++)
		a[i]=i;
}
int find(int x)
{
	return a[x]==x?x:a[x]=find(a[x]);
}
void unio(int x,int y)
{
	int xx=find(x);
	int yy=find(y);
	if(xx!=yy)
		a[xx]=yy;
}
void Kruskal()
{
	int sumw=0;
	int num1=0;
	int u,v,i;
	init();
	for(i=0;i<bian;i++)
	{
		u=G[i].u;
		v=G[i].v;
		if(find(u)!=find(v))
		{
			printf( "( %d , %d ) w = %d\n", u, v, G[i].w );
			unio(u,v);
			sumw+=G[i].w;
			num1++;
		}
		if(num1==num)
			break;
	}
	printf("\n\tsum = %d",sumw);
}
int main()
{
	int i,u,v,w;
	scanf("%d%d",&num,&bian);
	for(i=0;i<bian;i++)
	{
		scanf("%d%d%d",&u,&v,&w);
		G[i].u=u;
		G[i].v=v;
		G[i].w=w;
	}
	sort(G,G+bian,cmp);
	Kruskal();
	printf("\n");
} 
/*
7 12
0 1 2
0 2 4
0 3 1
1 3 3
1 4 10
2 3 2
2 5 5
3 5 8
3 6 4
3 4 7
5 6 1
4 6 6
*/

Dijkstra最短路径算法

最经典的求最短路径算法

#include<bits/stdc++.h>
#define inf 99999
using namespace std;
int mp[100][100];
int dis[100];
int vis[100];
int num;
void Dijkstra(int x)
{
	int i,j;
	vis[x]=1;
	for(i=0; i<num; i++)
		dis[i]=mp[x][i];
	int u;
	for(i=1; i<num; i++)
	{
		int min=inf;
		u=x;
		for(j=0; j<num; j++)
		{
			if(vis[j]==0&&min>dis[j])
				min=dis[u=j];
		}
		vis[u]=1;
		for(j=0; j<num; j++)
		{
			if(vis[j]==0&&min+mp[u][j]<dis[j])
				dis[j]=mp[u][j]+min;
		}
	}
}
void init()
{
	int i,j;

	memset(vis,0,sizeof(vis));
	memset(dis,0,sizeof(dis));
}
int main()
{
	int bian,i,j,x,y,w;
	scanf("%d%d",&num,&bian);
	for(i=0; i<bian; i++)
		for(j=0; j<bian; j++)
			mp[i][j]=inf;
	for(i=0; i<bian; i++)
	{
		scanf("%d%d%d",&x,&y,&w);
		mp[x][y]=w;
	}
	for(i=0; i<num; i++)
	{
		init();
		Dijkstra(i);
		for(j=0; j<num; j++)
		{
			if(j!=i)
				printf("v(%d) ---> (%d) = %d\n",i,j,dis[j]);
		}
		printf("\n");
	}

}
/*
5 9
0 1 3
0 4 30
1 2 25
1 3 8
2 4 10
3 2 4
3 0 20
3 4 12
4 0 5
*/

关键路径

关键路径可以说是很实用的算法了,在各个工程中使用最多
写起来也比较繁琐

#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
struct node{
	int u,v,w;
}e[100];
int n,m,into[100],Stack[100], mp[100][100];
int inf=999999,min;
int ve[100],vl[100],ee[100],el[100];
void topo()//拓扑求最大路径
{
	int cnt = 0;//栈顶指针为零
	for(int i = 1; i <= n; i++) //数次寻找
	{
		int k=-1;
		for(int j=1; j<= n; j++)
		{
			if(into[j]==0)//如果入度为0,可以进栈了
			{
				Stack[++cnt] = j;
				k = j;
				into[j] = -1;
				break;//如果有为零的就可以立刻结束
			}
		}
		for(int j = 1; j <= n; j++)
			if(mp[k][j] != inf)//假如联通
			{
				ve[j] = max(ve[j], ve[k] + mp[k][j]);//找到最大路径
				into[j]--;//入度减一
			}
	}
}
void solve()
{
	topo();
	memset(vl, inf, sizeof(vl));//最晚发生时间初始为最大
	vl[Stack[n]] = ve[Stack[n]];//最晚等于最大路径
	for(int i = n; i >= 1; i--) //从后向前找
		for(int j = 1; j <= n; j++)
			if(mp[Stack[i]][j] != inf) //如果两点之间有联系
				vl[Stack[i]] = (vl[j] - mp[Stack[i]][j])< vl[Stack[i]]?(vl[j] - mp[Stack[i]][j]):vl[Stack[i]];//更新最晚时	
	for(int i = 1; i <= m; i++) //计算ee
		ee[i] = ve[e[i].u];
	for(int i = 1; i <= m; i++)//计算el
		el[i] = vl[e[i].v] - e[i].w;
	printf("\n");
	for(int i = 1; i <= m; i++)
		if(ee[i] == el[i]) 
			printf("%d %d %d\n", e[i].u, e[i].v, e[i].w);//输出关键路径
}
int main()
{
	scanf("%d%d", &n, &m);
	for(int i=0;i<=100;i++)
		for(int j=0;j<=100;j++)
			mp[i][j]=inf;   //将未联通的点初始为最大值
	for(int i = 1; i <= m; i++)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		e[i].u  = u;
		e[i].v  = v;
		e[i].w  = w;
		mp[u][v] = w;
		into[v]++;//入度增加
	}
	solve();
	return 0;
}

图论小综合(校园导航系统)

学习完图论,做了一个小系统玩,校园导航
用到了最短路径和路径打印,还有一个弗洛伊德算法,没有用到。

#include <stdio.h>
#include<windows.h>
#include <string.h>
#include<memory.h>
#define MaxSightNum 100
#define inf 9999999
typedef struct//SightType
{
	int num;
	char name[100];
	char feature[200];
}SightType;
typedef struct //MGragh
{
	SightType sights[MaxSightNum];
	int edges[MaxSightNum][MaxSightNum];
	int n,e;
}MGraph;
MGraph hbu;
int stack[1000];
int top=-1;
int Dis[MaxSightNum];
int vis[MaxSightNum];//是否访问过 
int path[MaxSightNum];//前驱景点 
char name[][12]={"校医院","操场","校门西口","古楼实验室","校门南门","图书馆","大食堂","信息院楼","综合楼","男生宿舍",
						"女生宿舍","超市"}; 
char feature[][100]={"这里是学校医务室","运动的地方","西门有小吃","我们上实验的地方","学校大门口","看书的地方","吃饭的地方,饭很好吃",
						"信息院老师办公的地方","很高","男生宿舍","女生宿舍","买一些生活用品"}; 
void Mmenu()//主菜单 
{
	printf("			欢迎使用河北农业大学校园导航系统 \n\n\n");
	printf("			1.管理者模式\n");
	printf("			2.游客模式\n");
	printf("			3.退出\n");
	printf("			请输入您想进入的模式: ");
}
void map()//地图 
{
	
}
void creat()//创建地图 
{
	int  i,j;
	hbu.e=20;
	hbu.n=12;
	for(i=0;i<hbu.n;i++)
	{
		hbu.sights[i].num=i;
		strcpy(hbu.sights[i].name,name[i]); 
		strcpy(hbu.sights[i].feature,feature[i]); 
	}
	for(i=0;i<hbu.e;i++)
	{
		for(j=0;j<hbu.e;j++)
		{
			hbu.edges[i][j]=inf;
		}
	}
	hbu.edges[0][1]=hbu.edges[1][0]=350;
	hbu.edges[0][4]=hbu.edges[4][0]=200;
	hbu.edges[1][2]=hbu.edges[2][1]=200;
	hbu.edges[1][4]=hbu.edges[4][1]=480;
	hbu.edges[1][5]=hbu.edges[5][1]=280;
	hbu.edges[2][3]=hbu.edges[3][2]=100;
	hbu.edges[2][6]=hbu.edges[6][2]=100;
	hbu.edges[3][6]=hbu.edges[6][3]=100;
	hbu.edges[4][5]=hbu.edges[5][4]=400;
	hbu.edges[4][7]=hbu.edges[7][4]=500;
	hbu.edges[4][8]=hbu.edges[8][4]=500;
	hbu.edges[5][9]=hbu.edges[9][5]=50;
	hbu.edges[5][10]=hbu.edges[10][5]=300;
	hbu.edges[6][10]=hbu.edges[10][6]=100;
	hbu.edges[7][11]=hbu.edges[11][7]=400;
	hbu.edges[8][11]=hbu.edges[11][8]=400;
	hbu.edges[8][9]=hbu.edges[9][8]=100;
	hbu.edges[9][11]=hbu.edges[11][9]=500;
	hbu.edges[9][10]=hbu.edges[10][9]=200;
	hbu.edges[10][11]=hbu.edges[11][10]=600;
}
void amenu()//管理者菜单 
{
	printf("\n\n\n\n			1.浏览景点信息。\n");
	printf("			2.某一景点到其他景点的最短信息。\n");
	printf("			3.任意两景点的最短路径。\n");
	printf("			4.修改景点信息。\n");
	printf("			5.增加景点。\n");
	printf("			6.删除景点\n");
	printf("			7.增加道路。\n");
	printf("			8.删除道路。\n");
	printf("			9.返回。\n");
	printf("			请输入您的操作选项: ");
}
void tmenu()//游客菜单 
{
	printf("\n\n\n\n			1.浏览景点信息。\n");
	printf("			2.某一景点到其他景点的最短信息。\n");
	printf("			3.任意两景点的最短路径。\n");
	printf("			4.返回。\n");
	printf("			请输入您的操作选项: ");
}
void print(SightType a)//景点信息输出 
{
	printf("\n		景点名字:%s",a.name);
	printf("\n		景点编号:%d",a.num);
	printf("\n		景点介绍:%s\n",a.feature);
	system("pause");
	system("cls");
}
int searchSight(char sname[])//返回景点编号 
{
	int i;
	for(i=0;i<hbu.n;i++)
	{
		if(strcmp(hbu.sights[i].name,sname)==0)
		{
			return i;
		}
	 }
	 return -1;
}
void GetSightInfo()//景点信息查询 
{
	char sname[20];//景点名称;
	int i; 
	map();
	system("cls");
	printf("请输入你要查询信息的景点的名称: ");
	scanf("%s",&sname);
	i=searchSight(sname);
	if(i==-1)
	{
		printf("\n			没有找到!\n\n\n"); 
	}
	else
	{
		print(hbu.sights[i]);
	}
	system("pause");
	system("cls");
} 
void dijkstra(int s)//dijkstra算法 
{
	//printf("%d\n",s);
	int i=0,j,k;
	memset(vis,0,sizeof(vis));//数组清零 
	vis[s]=1;
	for(i=0;i<hbu.n;i++)
	{
		Dis[i]=hbu.edges[s][i];
		path[i]=s;
	}
	path[s]=-1;
	for(i=1;i<hbu.n;i++)
	{
		int min=inf+1;
		for(j=0;j<hbu.n;j++)
		{
			if(vis[j]==0&&min>Dis[j])
			{
				min=Dis[j];
				k=j;
			}
		}
		vis[k]=1;
		for(j=0;j<hbu.n;j++)
		{
			if(vis[j]==0&&min+hbu.edges[k][j]<Dis[j])
			{
				Dis[j]=min+hbu.edges[k][j];
				path[j]=k;
			}
		}
	}
}
void printShortest(int s) //输出一个景点到其他景点的最短路径 
{
	int i;
	for(i=0;i<hbu.n;i++)
	{
		if(i!=s)
		{
			if(Dis[i]!=inf)
			{
			printf("\n%s->%s : %d :",name[s],name[i],Dis[i]);
			int pre;
			pre=path[i];
			while(pre>=0)
			{
				stack[++top]=pre;
				pre=path[pre];
			//	printf("%d\n",pre);
			} 
			while(top>0)
			{
				printf("%s->",name[stack[top--]]);
			} 
			printf("%s",name[i]);
			}
			else
			{
				printf("\n%s->%s :\t无通路!",name[s],name[i]);
			}
		} 
	}
}
void ShortestPath()//一个景点到其他景点的最短路径 
{
	int s;//查询景点的编号 
	int i=0;
	char name[20];查询景点的名称 
	system("cls");
	printf("请输入要查询的景点名字: ");
	scanf("%s",&name);
	for(i=0;i<hbu.n;i++)
	{
		if(strcmp(hbu.sights[i].name,name)==0)
		{
			s=hbu.sights[i].num;
			break;
		}
	}
	if(i==hbu.n)
	{
		printf("输入不合法!\n");
		return ; 
	}
	dijkstra(s);
	printShortest(s);
	printf("\n\n\n");
	system("pause");
	system("cls");
}
void changeSightInfo()//修改景点信息
{
	char sname[20];//景点名称;
	char feature[100];
	int i; 
	map();
	system("cls");
	printf("请输入你要修改信息的景点名称: ");
	scanf("%s",&sname);
	i=searchSight(sname);
	if(i!=-1)
	{
		printf("请输入你要修改的描述信息: ");
		scanf("%s",&feature);
		strcpy(hbu.sights[i].feature,feature);
		print(hbu.sights[i]);
		printf("\n\n\n\n\t\t\t\t修改成功!!"); 
		system("pause");
		system("cls");
	}
	else
	{
		printf("\n\n\n\n\t\t\t\t!!");
	}
}
void TwoShortest()//求两个景点之间的最短路径 
{
	int j,k;
	char start[20];
	char end[20];
	int pre;
	system("cls");
	printf("请输入起始景点: ");
	while(1)
	{
		scanf("%s",&start);
		k=searchSight(start);
		if(k!=-1)
			break;
		else
			printf("没有找到该景点,请重新输入!\n");
	}
	printf("请输入终止景点: ");
	while(1)
	{
		scanf("%s",&end);
		j=searchSight(end);
		if(j!=-1)
			break;
		else
			printf("没有找到该景点,请重新输入!\n");
	}
	dijkstra(k);
	if(Dis[j]!=inf)
	{
		printf("\n%s->%s : %d :",start,end,Dis[j]);
		pre=path[j];
		while(pre>=0)
		{
			stack[++top]=pre;
			pre=path[pre];
		} 
		while(top>0)
			printf("%s->",name[stack[top--]]);
		printf("%s",name[j]);
	}
	else
		printf("\n\n\n\t\t\t没有通路!\n\n");
	printf("\n\n\n");
	system("pause");
	system("cls");
}
void addSight()//添加一个景点 
{
	int i,w,t, distance;
	char end[20];
	system("cls");
	printf("请输入你要增加的景点名称: ");
	scanf("%s",&hbu.sights[hbu.n++].name);
	strcpy(name[hbu.n-1],hbu.sights[hbu.n-1].name);
	hbu.sights[hbu.n-1].num=hbu.n-1;
	printf("请输入该景点的描述信息: ");
	scanf("%s",&hbu.sights[hbu.n-1].feature);
	printf("请输入该景点与其他景点间的路径数:");
	scanf("%d",&w);
	for(i=0;i<w;i++)
	{
		printf("请输入第%d条路径的另一个景点名称: ",i+1);
		scanf("%s",&end);
		t=searchSight(end);
		printf("请输入两景点之间的距离: ");
		scanf("%d",&distance);
		hbu.edges[t][hbu.n-1]=hbu.edges[hbu.n-1][t]=distance;
		hbu.e++;
	}
	print(hbu.sights[hbu.n-1]);
	printf("增加成功!!!\n\n\n");
	system("pause");
	system("cls");
}
void deleteSight()//删除一个景点 
{
	int i,d;
	char del[20];
	system("cls");
	printf("请输入你要删除的景点名称: ");
	scanf("%s",&del);
	d=searchSight(del);
	strcpy(hbu.sights[d].feature,"已删除");
	for(i=0;i<hbu.n;i++)
	{
		hbu.edges[i][d]=inf;
		hbu.edges[d][i]=inf;
	}
	printf("\n\n\n\t\t\t\t已删除!\n\n\n");
	system("pause");
//	system("pause");
	system("cls");
}
void addEdges()//增加道路 
{
	system("cls");
	int v,s,e,i,adde;
	char start[20],end[20];
	printf("请输入你要增加的道路数: ");
	scanf("%d",&adde);
	for(i=0;i<adde;i++)
	{
		printf("请输入所添加道路的起点: ");
		scanf("%s",start);
		printf("请输入所添加道路的终点: ");
		scanf("%s",end);
		printf("请输入两个景点之间的距离: "); 
		scanf("%d",&v);
		s=searchSight(start);
		e=searchSight(end);
		hbu.edges[s][e]=hbu.edges[e][s]=v;
	}
	printf("\n\n\n\t\t\t添加成功!!\n\n");
	system("pause");
	system("cls");
}
void deleteEdges()//删除道路 
{
	system("cls");
	char start[20],end[20];
	int  i,dele;
	printf("请输入你要删除的道路数: ");
	scanf("%d",&dele);
	for(i=0;i<dele;i++)
	{
		printf("请输入所删除道路的起点: ");
		scanf("%s",start);
		printf("请输入所删除道路的终点: ");
		scanf("%s",end);
		hbu.edges[searchSight(start)][searchSight(end)]=inf; 
	}
	printf("\n\n\n\t\t\t删除成功!!\n\n");
	system("pause");
	system("cls");
}
int main()
{   
	int order=1,torder=1,aorder=1;// 主界面命令,游客界面命令,管理者界面命令 
	creat();
	while(1)
	{
		system("cls");
		Mmenu();
		scanf("%d",&order);
		if(order==1)
		{
			system("cls");
			map();
			while(1)
			{
				amenu();
				scanf("%d",&aorder);
				if(aorder==9)
				{
					printf("\n\n\n\n\t\t\t感谢使用!!\n\n\n") ;
						break;
				}
				switch(aorder)
				{
				case 1://获取景点信息 
					{
						GetSightInfo();
						break;
					}
				case 2://求一个景点到其他景点的最短路径 
					{
						
						ShortestPath();
						break;
					}
				case 3://求两个景点之间的最短路径 
					{
						TwoShortest(); 
						break;
					}
				case 4://修改景点信息 
					{
						changeSightInfo();
						break;
					}
				case 5://增加景点
					{
						addSight();
						break;
					}
				case 6://删除一个景点 
					{
						deleteSight();
						break;
					}
				case 7://增加道路 
					{
						addEdges(); 
						break;
					}
				case 8://删除道路; 
					{
						deleteEdges();
						break;
				 	} 
				default:
					{
						printf("\n\n\n\n\t\t\t输入不合法!!");
						system("pause");
						system("cls");
					}
				}
			}
		}
		else if(order==2)
		{
			system("cls");
			map();
			while(1)
			{
				tmenu();
				scanf("%d",&torder);
				if(torder==4)
				{
					printf("\n\n\n\n\n\t\t\t\t感谢使用!"); 
						break;
				}
				switch(torder)
				{
				case 1://获取景点信息 
					{
						GetSightInfo();
						break;
					}
				case 2://求一个景点到其他景点的最短路径 
					{
						
						ShortestPath();
						break;
					}
				case 3://求两个景点之间的最短路径 
					{
						TwoShortest(); 
						break;
					}
				default: 
					{
						printf("\n\n\n\n\t\t\t输入不合法!!");
						system("pause");
						system("cls");
					}
				}
			}
			
			
		}
		else if(order==3)// 退出 
		{
			system("cls");
			printf("\n\n\n\n\t\t\t感谢使用!!"); 
			return 0;
		}
		else //输入有误 
		{
			printf("\n\n\n			输入不合法!\n");
			system("pause");
		}
	}
}

番外篇

飞机大战小游戏

一个很简单的小游戏,在实验课上闲着没事写的

# include<stdio.h>
# include<windows.h>
# include<conio.h>
void chushihua();
void show();
void yhxiangguan();
void yhwuguan();
void HideCursor();
void gotoxy(int x,int y);

int high,wight;
int plane_x,plane_y;
int zidan_x,zidan_y;
int diji_x,diji_y;
int count=0; 
int f=1;
char s='|';

int main()
{
	chushihua();
	while(1)
	{
		gotoxy(0,0);
		HideCursor();
		show();
		yhxiangguan();
		yhwuguan();
		if(f==0)
			break;
		printf("得分:%d\n",count);
		printf("1--切换激光炮\n");
		printf("2--切换月牙炮\n");
		printf("3--切换粒子炮\n");
		
	}
	system("cls");
	printf("Game Over!!!\n得分:%d",count);
}

void chushihua()
{
	high=20;
	wight=30;
	plane_x=wight/2;
	plane_y=high/2;
	zidan_x=-1;
	zidan_y=plane_y;
	diji_x=wight/2;
	diji_y=1;
}

void show()
{
//	system("cls");
	int i,j;
	for(i=0;i<high;i++)
	{
		for(j=0;j<wight;j++)
		{
			if(j==plane_x&&i==plane_y)
				printf("*");
//			else if(j==wight-1||j==0||i==high-1||i==0)
//				printf("#");
			else if(j==zidan_x&&i==zidan_y)
				printf("%c",s);
			else if(j==diji_x&&i==diji_y)
				printf("@");
			else
				printf(" ");
		}
		printf("\n");
	}
}

void yhxiangguan()
{
	char input;
	if(kbhit())
	{
		input=getch();
		if(input=='w')
			plane_y--;
		if(input=='s')
			plane_y++;
		if(input=='a')
			plane_x--;
		if(input=='d')
			plane_x++;
		if(input==' ')
		{
			zidan_x=plane_x;
			zidan_y=plane_y-1;
		}
		if(input=='1')
			s='|';
		if(input=='2')
			s='^';
		if(input=='3')
			s='.';
	}
}

void yhwuguan()
{
	static int speed=0;
	if(zidan_y>-1)
	{
		
		zidan_y--;
	}
		
	if(diji_y<high)
	{
		speed++;
		if(speed==10)
		{
			diji_y++;
			speed=0;
		}
	}
	if(diji_y==high-1)
		diji_y=1;
	if(diji_y==zidan_y&&diji_x==zidan_x)
	{
		diji_y=0;
		diji_x=rand()%20;
		count++;
		zidan_x=plane_x;
		zidan_y=-1;
	}
	if(plane_x==diji_x&&plane_y==diji_y)
		f=0;
}

void HideCursor()
{
 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x,int y)  //光标移动到(x,y)位置 
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle,pos);
}
  • 13
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实验1:顺序表基本操作 一、实验目的 1.学会定义线性表的顺序存储类型,实现C程序的基本结构,对线性表的一些基本操作和具体的函数定义。 2.掌握顺序表的基本操作,实现顺序表的插入、删除、查找以及求并集等运算。 3.掌握对多函数程序的输入、编辑、调试和运行过程。 二、实验要求 1.预习C语言中结构体的定义与基本操作方法。 2.对顺序表的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容: 1.编写程序实现顺序表的下列基本操作: (1)初始化顺序表La。 (2)将La置为空表。 (3)销毁La。 (4)在La中插入一个新的元素。 (5)删除La中的某一元素。 (6)在La中查找某元素,若找到,则返回它在La中第一次出现的位置,否则返回0。 (7)打印输出La中的元素值。 2.编写程序完成下面的操作: (1)构造两个顺序线性表La和Lb,其元素都按值非递减顺序排列。 (2)实现归并La和Lb得到新的顺序表Lc,Lc的元素也按值非递减顺序排列。 (3)假设两个顺序线性表La和Lb分别表示两个集合A和B,利用 union_Sq操作实现A=A∪B。 四、思考与提高 假设两个顺序线性表La和Lb分别表示两个集合A和B,如何实现A=A ∩B ? 实验2:单链表基本操作 一、 实验目的 1. 学会定义单链表的结点类型,实现对单链表的一些基本操作和具体的函数定义,了解并掌握单链表的类定义以及成员函数的定义与调用。 2. 掌握单链表基本操作及两个有序表归并、单链表逆置等操作的实现。 二 、实验要求 1.预习C语言中结构体的定义与基本操作方法。 2.对单链表的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.编写程序完成单链表的下列基本操作: (1)初始化单链表La。 (2)在La中第i个元素之前插入一个新结点。 (3)删除La中的第i个元素结点。 (4)在La中查找某结点并返回其位置。 (5)打印输出La中的结点元素值。 2 .构造两个带有表头结点的有序单链表La、Lb,编写程序实现将La、Lb合并成一个有序单链表Lc。 合并思想是:程序需要3个指针:pa、pb、pc,其中pa,pb分别指向La表与Lb表中当前待比较插入的结点,pc 指向Lc表中当前最后一个结点。依次扫描La和Lb中的元素,比较当前元素的值,将较小者链接到*pc之后,如此重复直到La或Lb结束为止,再将另一个链表余下的内容链接到pc所指的结点之后。 3.构造一个单链表L,其头结点指针为head,编写程序实现将L逆置。(即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。) 四、思考与提高 1.如果上面实验内容2中合并的表内不允许有重复的数据该如何操作? 2.如何将一个带头结点的单链表La分解成两个同样结构的单链表Lb,Lc,使得Lb中只含La表中奇数结点,Lc中含有La表的偶数结点? 实验3:循环队列基本操作 一 、实验目的 1.熟悉并能实现循环队列的定义和基本操作。 2.了解用队列解决实际应用问题。 二、实验要求 1.进行队列的基本操作时要注意队列“先进先出”的特性。 2.复习关于队列操作的基础知识。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.任意输入队列长度和队列中的元素值,构造一个顺序循环队列,对其进行清空、插入新元素、返回队头元素以及删除队头元素操作。 2.约瑟夫环的实现:设有n个人围坐在圆桌周围,现从某个位置 i 上的人开始报数,数到 m 的人就站出来。下一个人,即原来的第m+1个位置上的人,又从1开始报数,再是数到m的人站出来。依次重复下去,直到全部的人都站出来,按出列的先后又可得到一个新的序列。由于该问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus 问题。 例如:当n=8,m=4,i=1时,得到的新序列为: 4,8,5,2,1,3,7,6 编写程序选择循环队列作为存储结构模拟整个过程,并依次输出出列的各人的编号。 实验4:矩阵的压缩存储及相关操作 (第11周星期三7、8节) 一 、实验目的 1.掌握下三角矩阵的输入、输出、转置算法。 2.理解稀疏矩阵的三元组表类型定义,掌握稀疏矩阵的输入、输出、转置算法。 二 、实验要求 1.认真阅读和掌握本实验的算法思想。 2.编写完整程序完成下面的实验内容并上机运行。 三、实验内容 1.所谓上(下)三角矩阵是指矩阵的下(上)三角中的元素均为常数或零的n阶矩阵。此时除了存储上(下)三角矩阵中的元素之外再加一个存储常数的空间即可。三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好有n×(n+1)/2个,因此,三角矩阵可压缩到向量Sa[0……n×(n+1)/2]中,其中c存放在向量的最后一个分量中。用向量Sa[0……n×(n+1)/2]压缩存储下三角矩阵,编写程序任意输入一个下三角矩阵,对其进行转置,输出转置后的矩阵。 2.用三元组顺序表压缩存储稀疏矩阵,编写程序任意输入一个稀疏矩阵,对其进行转置,输出转置后的矩阵。 四、思考与提高 如何计算一个三元组表表示的稀疏矩阵对角线元素之和以及两个三元组表表示的稀疏矩阵的乘积? 实验5:二叉树的建立及遍历 (第十三周星期三7、8节) 一 、实验目的 1.学会实现二叉树结点结构和对二叉树的基本操作。 2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。 2 .编写程序生成下面所示的二叉树,并采用中序遍历的非递归算法对此二叉树进行遍历 四、思考与提高 1.如何计算二叉链表存储的二叉树中度数为1的结点数? 2.已知有—棵以二叉链表存储的二叉树,root指向根结点,p指向二叉树中任一结点,如何求从根结点到p所指结点之间的路径? 实验6:二分查找、Hash查找算法的程序实现 (第十五三周星期三7、8节) 一、 实验目的 1 .熟练掌握二分查找算法并能在有序表中进行查找操作。 2. 掌握Hash表的相关算法。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.复习顺序表及二叉树的基本操作过程。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.二分查找又称为折半查找,它要求要查找的顺序表必须是有序表,即表中结点按关键字有序.并且要用顺序存储结构。 基本思想是:首先将给定值key与表中中间位置记录的关键字相比较,若二者相等,则查找成功,否则根据比较的结果确定下次查找的范围是在中间记录的前半部分还是后半部分,然后在新的查找范围内进行同样的查找,如此重复下去,直到在表中找到关键字与给定值相等的记录,或者确定表中没有这样的记录。 编写程序构造一个有序表La,从键盘接收一个关键字key,用二分查找法在La 中查找key,若找到则提示查找成功并输出key所在的位置,否则提示没有找到信息。 2.编写程序实现Hash表的建立、删除、插入以及查找操作。 程序应包含的主要功能函数有: Hash( ):计算哈希地址 InitialHash( ):初始化哈希表 SearchHash( ):在哈希表中查找关键字 InsertHash( ):向哈希表中插入关键字 DeleteHash( ):删除哈希表中某一关键字 PrintHash ( ):打印输出哈希表 四、思考与提高 如何利用二分查找算法在一个有序表中插入一个元素x,并保持表的有序性? 实验7:至少三种排序算法的程序实现 (第十六周星期三7、8节) 一、 实验目的 1.掌握简单插入排序、冒泡排序、快速排序、堆排序以及归并排序的算法并加以应用。 2.对各种查找、排序技术的时间、空间复杂性有进一步认识。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 编写程序实现下述五种算法至少三种,并用以下无序序列加以验证: 49,38,65,97,76,13,27,49 1.简单插入排序 2.冒泡排序 3.快速排序 4.归并排序 5.堆排序 四、思考与提高 1.设有1000个无序的元素,希望用最快的速度挑出其中前10个最大的元素,采用哪一种排序方法最好?为什么? 2.如何构造一种排序方法,使五个整数至多用七次比较就可以完成排序任务? 实验8:集成实验 一、 实验目的 目的:扩大编程量,完成模块化程序设计的全过程。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 将已经实现的模块装配在一起,由菜单进行管理,形成一个小型多功能软件。 while(1){ menuList(); scanf(&n); switch(n){ case 1:……;break; case 2:……;break; . . case 0:return; } } 如: • MenuSelect( ){ int select; SqList A , B , C ; MenuList( ); /* 打印菜单 */ scanf(“%d”,&select;); switch(select){ case 1: InitList_Sq( &A ); break; case 2: InitList_Sq( &B ); break; case 3: Insert(&A);break; case 4: Insert(&B );break; case 5: Union(&A ,B);break; ………….. default: printf(“\n ERROR\n”); } } 四、思考与提高 1. 优化已完成的程序,使整个实验形成至少三级菜单管理; 2.美化输出界面,使得操作友好。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值