目录
数据结构实验——顺序表的基本操作
数据结构实验——单链表的基本操作
数据结构实验——顺序栈的建立及基本操作实现
数据结构实验——链队列的建立及基本操作实现
数据结构实验——赫夫曼树构造及赫夫曼编码的实现
数据结构实验——迪杰斯特拉算法求最短路径
/*-----顺序表的基本操作-----*/
#include
#include
#define maxsize 1024
typedef char elemtype;
typedef struct
{
elemtype list[maxsize];
int length;
}sequenlist;
void creatlist(sequenlist *L)
{
int n,i;
char tmp;
printf("请输入数据的个数:\n");
scanf("%d",&n);
printf("请按顺序输入各个值:\n");
for(i=0;ilist[i]=tmp;
}
L->length=n;
printf("\n");
}
//插入元素
int insert(sequenlist *L,elemtype x,int i) //i用来表示插入位置
{
int j;
if(L->length==maxsize)
{
printf("overflow\n");
return 0;
}
else if((i<1)||(i>L->length+1)) //length+1表示在表尾插入
{
printf("error,please input the right'i'\n");
return 0;
}
else
{
for(j=L->length-1;j>=i-1;j--)
L->list[j+1]=L->list[j];
L->list[i-1]=x;
L->length=L->length+1;
return 1;
}
}
//删除元素
int dellist(sequenlist *L,int i) //i表示删除的位置
{
if((i<1)||(i>L->length))
{
printf("error,please input the right 'i'\n");
return 0;
}
else
{
for(;ilength;i++)
L->list[i-1]=L->list[i];
L->length=L->length-1;
return 1;
}
}
void printout(sequenlist *L)
{
int i;
for(i=0;ilength;i++)
{
printf("list[%d]=",i);
printf("%c\n",L->list[i]);
}
}
int main()
{
sequenlist *L;
char cmd,x;
int i;
L=(sequenlist *)malloc(sizeof(sequenlist));
creatlist(L);
printout(L);
do
{
printf("i,I...插入\n");
printf("d,D...删除\n");
printf("q,Q...退出\n");
do
{
fflush(stdin);
scanf("%c",&cmd);
}
while((cmd!='d')&&(cmd!='D')&&(cmd!='q')&&(cmd!='Q')&&(cmd!='i')&&(cmd!='I'));
switch(cmd)
{
case'i':
case'I':
printf("请输入要插入的数据:");
fflush(stdin);
scanf("%c",&x);
printf("请输入要插入的位置:");
scanf("%d",&i);
insert(L,x,i);
printout(L);
break;
case'd':
case'D':
printf("请输入要删除的数据的位置:");
fflush(stdin);
scanf("%d",&i);
dellist(L,i);
printout(L);
break;
}
}
while((cmd!='q')&&(cmd!='Q'));
}
/*-----单链表的基本操作-----*/
#include
#include
typedef int Elemtype;
typedef int Status;
typedef struct node //定义存储节点
{
Elemtype data; //数据域
struct node *next;//结构体指针
} node,*linklist; //结构体变量,结构体名称
linklist creat(int n)//创建单链表,采用头插法建表
{
linklist head,p; //定义头指针head指针,p指针指向当前新生成的结点
int x,i;
head=(node *)malloc(sizeof(node));//生成头结点
head->next=NULL;
printf("输入结点值:\n");
for(i=n;i>0;i--) //for 循环用于生成第一个节点并读入数据
{
scanf("%d",&x);
p=(node *)malloc(sizeof(node));
p->data=x;//读入第一个节点的数据
p->next=head->next;//把第一个节点始终插在头结点的后面
head->next=p;//循环以便于生成第二个节点
}
return head;//返回头指针
}
void output(linklist head)//输出链表
{
linklist p;
p=head->next;
while(p)
{
printf("%3d",p->data);
p=p->next;
}
printf("\n");
}
Status insert(linklist &l,int i,Elemtype e) //插入操作
{
int j=0;
linklist p=l,s;
while(jnext;
++j;
}
if(!p||j>i-1)
printf("插入失败,请输入合理的插入位置\n");
else
{
s=(node *)malloc(sizeof(node));
s->data=e;
s->next=p->next;
p->next=s;
}
return 1;
}
Status delect(linklist &l,int i,Elemtype &e) //删除操作
{
int j=0;
linklist p=l,q;
while(jnext;
++j;
}
if(!p->next || j>i-1)
printf("删除失败,请输入合理的删除位置\n");
else
{
q=p->next;
p->next=q->next;
e=q->data;
free(q);
}
return 1;
}
Status GetElem(linklist l,int i,Elemtype &e) //查找操作
{
linklist p=l->next;
int j=1;
while(p&&jnext;
++j;
}
if(!p||j>i)
printf("查找失败,请输入合理的查找位置\n");
else
{
e=p->data;
printf("查找成功,要查找的元素为%d\n",e);
}
return 1;
}
int main()
{
linklist la;
int n;
int i;
Elemtype e;
char cmd;
printf("输入链表元素的个数:");
scanf("%d",&n);
la=creat(n);
printf("输出链表:\n");
output(la);
do
{
printf("g,G...查找\n");
printf("i,I...插入\n");
printf("d,D...删除\n");
printf("q,Q...退出\n");
do
{
scanf("%c",&cmd);
}
while((cmd!='g')&&(cmd!='G')&&(cmd!='d')&&(cmd!='D')&&(cmd!='q')&&(cmd!='Q')&&(cmd!='i')&&(cmd!='I'));
switch(cmd)
{
case'g':
case'G':
printf("请输入要查找元素的位置:\n");
scanf("%d",&i);
GetElem(la,i,e);
break;
case'i':
case'I':
printf("请输入要插入的数据:");
scanf("%d",&e);
printf("请输入要插入的位置:");
scanf("%d",&i);
insert(la,i,e);
output(la);
break;
case'd':
case'D':
printf("请输入要删除的位置:");
scanf("%d",&i);
delect(la,i,e);
output(la);
break;
}
}
while((cmd!='q')&&(cmd!='Q'));
}
#include
#include
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int status;
typedef struct{
int *base;
int *top;
int stacksize;
}sqstack;
/**------------对栈进行初始化-----------**/
status initstack(sqstack &s){
//构造一个空栈由指针s指出
s.base = (int *)malloc(STACK_INIT_SIZE*sizeof (int));
if (!s.base) exit (OVERFLOW); //存储分配失败
s.top = s.base;
s.stacksize = STACK_INIT_SIZE;
return OK;
}
/**----------------进栈---------------**/
status push(sqstack &s,int e){
//元素e插入到栈中,成为新的栈顶
if(s.top-s.base>=s.stacksize) //栈满,增加存储空间
{
s.base=(int*)realloc(s.base,(s.stacksize+STACKINCREMENT)* sizeof(int));
if (!s.base) exit (OVERFLOW); //存储分配失败
s.top = s.base + s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++ = e; //插入新的栈顶元素,指针top增1
return OK;
}
/**-------------获得栈顶元素--------------**/
status gettop(sqstack &s,int &e){
//若栈不空,用e返回栈顶元素,并返回OK,则返ERROR
if(s.top == s.base) return ERROR; //栈空
e = *(s.top-1); //取栈顶元素,用e返回
return OK;
}
/**---------------出栈------------------**/
status pop(sqstack &s,int &e){
/*若栈不空,删除栈顶元素用e返回其值,并返回OK,否则返回ERROR,栈中下一元素所在位置成为新的栈顶*/
if(s.top == s.base) return ERROR; //栈空
e = * -- s.top; //删除栈顶元素,指针top减1
return OK;
}
/**-----------------打印----------------**/
status printstack(sqstack s){
if(s.base==s.top)
{
printf("空栈\n");
return OK;
}
else
{
printf("从栈底到栈顶,栈内容是:\n");
for(;s.base!=s.top;s.base++)
printf(" %d ",*s.base);
}
printf("\n");
return OK;
}
int main(){
sqstack s;
if(initstack(s))
printf("初始化栈成功\n");
do{
printf("********************************************\n");
printf("* 请选择要进行的操作: *\n");
printf("* 1 进栈 2 打印 3 出栈 *\n");
printf("* 4 获得栈顶元素 0 退出 *\n");
printf("********************************************\n");
int select;
scanf("%d", &select);
if(select==0)
break;
switch(select){
case 0:
break;
case 1:
int pushelem,n,i;
printf("输入要进栈的元素个数:");
scanf("%d",&n);
printf("依次输入要进栈的元素: \n");
for(i=1;i<=n;i++){
scanf("%d",&pushelem);
if(push(s,pushelem))
printf("元素%d进栈成功\n", pushelem);
else
printf("进栈失败\n");
}
break;
case 2:
printf("-----------------------------\n");
if(printstack(s))
printf("打印完毕\n");
break;
case 3:
int e,m;
printf("输入要出栈的元素个数: ");
scanf("%d",&m);
for(i=1;i<=m;i++){
if(pop(s,e))
printf("元素%d出栈\n",e);
else
printf("出栈失败\n");
}
break;
case 4:
if(gettop(s,e))
printf("栈顶元素是%d\n",e);
else
printf("获得栈顶元素失败\n");
break;
default:
printf("你进行了误操作,请重新选择\n:");
break;
}
}while(1);
return OK;
}
#include
#include
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef struct QNode
{
int data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;
/*****************链队列的初始化****************/
int InitQueue(LinkQueue &Q)
{
Q.front=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.rear=Q.front;
Q.front->next=NULL;
return OK;
}
/*************入队操作的实现******************/
int EnQueue(LinkQueue &Q,int e)
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
/***************出队操作的实现************/
int DeQueue(LinkQueue &Q,int &e)
{
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;
free(p);
return OK;
}
/**************遍历链式队列**************/
int PrintQueue(LinkQueue &Q)
{
QueuePtr p;
printf("链式队列中的元素为:");
if(Q.front->next!=NULL)
{
p=Q.front->next;
while(p)
{
printf("%5d",p->data);
p=p->next;
}
}
else
printf("队列为空");
printf("\n");
return OK;
}
int main()
{
LinkQueue Q;
InitQueue(Q);
int e,m;
do
{
printf("\n");
printf("----------------------------------------\n");
printf("1--插入元素;2--删除元素;0--结束运行\n");
printf("----------------------------------------\n");
printf("\n");printf("\n");
printf("请选择操作(1/2/0): ");
scanf("%d",&m);
if(m==0)
break;
switch(m)
{
case 1:
printf("插入元素:");
scanf("%d",&e);
if(EnQueue(Q,e))
printf("元素%d入队成功\n",e);
else
printf("元素%d入队失败\n",e);
PrintQueue(Q);
break;
case 2:
if(DeQueue(Q,e))
printf("元素%d出队成功\n",e);
else
printf("队列为空,出队失败\n");
PrintQueue(Q);
break;
default:
printf("你输入了误操作,请重新输入");
break;
}
} while(1);
return OK;
}
#include
#include
#include
//动态分配数组存储赫夫曼树
typedef struct{
int weight; //字符的权值
int parent,lchild,rchild; //字符的双亲及左右孩子
}HTNode,*HuffmanTree;
typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码,二维数组
//选择k个结点中无双亲且权值最小的两个结点
void Select(HuffmanTree &HT,int k,int &s1,int &s2){
int i;
i=1;
while(i<=k && HT[i].parent!=0)
i++;
//下面选出权值最小的结点,用s1指向其序号
s1=i;
for(i=1;i<=k;i++)
{
if(HT[i].parent==0 && HT[i].weight < HT[s1].weight)
s1=i;
}
//下面选出权值次小的结点,用s2指向其序号
for(i=1;i<=k;i++)
{
if(HT[i].parent==0 && i!=s1)
break;
}
s2=i;
for(i=1;i<=k;i++)
{
if(HT[i].parent==0 && i!=s1 && HT[i].weight < HT[s2].weight)
s2=i;
}
}
//构造Huffman树,求出n个字符的编码
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
//w是存放n个字符的权值的一维数组, n为叶子个数;构造赫夫曼树HT;
int m,c,f,s1,s2,i,start;
//m为结点总数,s1、s2分别记录权值最小的两个结点,i为循环变量,c,f是编码的辅助变量,start为在字符数组中编码结束符的位置
char *cd;//定义存储编码的一维数组
if(n<=1) return; //从函数中返回,没有返回值
m=2*n-1; //n个叶子结点,n-1个非叶子
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //预分配m+1个单元,0号单元未用
for(i=1; i<=n; i++)
{ //n个叶子结点赋初值,n个叶子最初为n个根结点
HT[i].weight=w[i]; //w的0号单元也没有值,从1号单元开始
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=n+1; i<=m; i++)
{ //从i=n+1开始,对另外n-1个结点赋初值
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(i=n+1; i<=m; i++)
{ //第i次循环时为第i个结点选择两个儿子结点s1与s2
Select(HT, i-1, s1, s2); // 在i-1棵子树中也即HT[1..i-1]中选择无父亲(parent为0)且权值最小的两个结点(其序号分别为s1和s2)。
HT[s1].parent=i; //修改结点s1的双亲值
HT[s2].parent=i; //修改结点s2的双亲值
HT[i].lchild=s1; //修改双亲结点的左孩子结点
HT[i].rchild=s2; //修改双亲结点的右孩子结点
HT[i].weight=HT[s1].weight+HT[s2].weight; //修改双亲结点的权值,建立父子关系
} //赫夫曼树HT构造完毕
//从叶子到根逆向求每个字符的赫夫曼编码
HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); //分配n个字符编码的头指针变量
cd=(char*)malloc(n*sizeof(char)); //分配求编码的工作空间(临时空间)
cd[n-1]='\0';//编码结束符
for(i=1;i<=n;i++)
{ //第i次循环时求第i个字符的赫夫曼编码
start=n-1; //start指向cd数组(即工作数组)中编码结束符的位置
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
{ //从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='0';//若当前结点是其父亲的左孩子,赋0值
else
cd[--start]='1'; //若当前结点是其父亲的右孩子,则赋1值
}
HC[i]=(char*)malloc((n-start)*sizeof(char)); //为存放第i个字符的编码申请空间
strcpy(HC[i],&cd[start]);//从cd复制编码到HC
}
free(cd); //释放工作空间
}
int main()
{
int n,i; //n为字符总个数,i为循环控制变量
int* w; //一维整型数组w记录权值
char* ch; //一维字符型数组ch记录字符
HuffmanTree HT;//定义指向结点类型的指针
HuffmanCode HC;//定义指向编码数组的指针
printf("请输入待编码的字符个数n=");
scanf("%d",&n);
w=(int*)malloc((n+1)*sizeof(int)); //记录权值,0号单元未用
ch=(char*)malloc((n+1)*sizeof(char));//记录字符,0号单元未用
printf("依次输入待编码的字符data及其权值weight:\n");
for(i=1;i<=n;i++)
{
printf("data[%d]=",i);
fflush(stdin);
scanf("%c",&ch[i]);
printf("weight[%d]=",i);
scanf("%d",&w[i]);
}
HuffmanCoding(HT,HC,w,n);
//输出字符及其编码
for(i=1;i<=n;i++)
printf("%c:%s\n",ch[i],HC[i]);
return 0;
}
#include
#define MAXVEXNUM 50 //最大顶点个数
#define INFINITY 65535 // INFINITY表示没有邻接的顶点间弧长
typedef char VertexType[3]; //定义存储顶点信息的数组,有3个单元,存储字符型数据
typedef struct vertex //定义顶点存储结构
{
int adjvex; //顶点编号
VertexType data; //顶点信息
}Vertex_Type; //顶点类型
typedef struct graph //定义图的存储结构
{
int Vertex_Num; //顶点数
int Edge_Num; //边数
Vertex_Type vexs[MAXVEXNUM]; //顶点数组
int edges[MAXVEXNUM][MAXVEXNUM]; // 边的二维数组
}AdjMatix; //图的邻接矩阵类型
/*--------生成邻接矩阵--------*/
int Create_Adjmatix(AdjMatix &g)
{
int i,j,k,b,t,w;
printf("请输入图的顶点数和边数:\n");
scanf("%d%d",&g.Vertex_Num,&g.Edge_Num);
for(i=0;i0)
g.edges[b][t]=w; //有邻接边的赋予权值
else
{
printf("输入错误!");
return 1;
}
}
for (i=0;i%s",g.vexs[k].data);
}
printf("\n");
printf("最短路径长度为:%d",dist[u]);
printf("\n");
}
else
{
printf("\n第%d次:",i);
for(m=0;m