《数据结构与算法》之课程实验

  • BSTree and AVLTree
    • BSTree
    • AVLTree
  • Top-K problem
  • Dijkstra
  • RandomData

电子科技大学《数据结构与算法》课程的3个实验,这里只展示代码,想要运行还得要对应的数据,用txt文件才能在命令行窗口调用运行。

BSTree and AVLTree

BSTree

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
using namespace std;#define MaxSize 100typedef int DataType;//二叉排序树结构定义
typedef struct node
{DataType data;struct node *lchild,*rchild;int flag;
}BSTNode,*BSTree;//初始化一个二叉排序树结点
BSTree InitNode(DataType data)
{BSTree Node=(BSTree)malloc(sizeof(BSTNode));Node->data=data;Node->lchild=NULL;Node->rchild=NULL;Node->flag=0;return Node;
}//若在二叉排序树中不存在关键字等于data的元素,插入该元素
void InsertBST(BSTree *root, DataType data)
{if(*root==NULL){*root=InitNode(data);}else {if(data<(*root)->data) InsertBST(&((*root)->lchild),data);else {if(data>(*root)->data) InsertBST(&((*root)->rchild),data);}}
}//从文件输入元素的值,创建相应的二叉排序树
void CreateBST(BSTree *root,const char *filename)
{ FILE *fp;DataType keynumber;*root=NULL;fp=fopen(filename,"r+");if(fp==NULL) exit(0x01);while(EOF!=fscanf(fp,"%d",&keynumber)) InsertBST(root,keynumber);
}//先序遍历二叉树, root为指向二叉树根结点的指针
void PreOrderCleanFlag(BSTree root)
{if(root!=NULL){root->flag=0;PreOrderCleanFlag(root->lchild);PreOrderCleanFlag(root->rchild);}
}//中序遍历二叉树, root为指向二叉树根结点的指针
void InOrder(BSTree root)
{if(root!=NULL){InOrder(root->lchild);printf("%d ",root->data);InOrder(root->rchild);}
}//后序遍历二叉树, root为指向二叉树根结点的指针
void PostOrder(BSTree root)
{if(root!=NULL){PostOrder(root->lchild);PostOrder(root->rchild);printf("%d ",root->data);}
}//层序遍历, root为指向二叉树根结点的指针
void LevelOrder(BSTree root)
{//定义一个队列 BSTree Queue[MaxSize];int front=-1,rear=0;// 若二叉树为空,遍历结束 if(root==NULL) return;//根结点进入队列 Queue[rear]=root;//若队列不为空,遍历,否则,遍历结束 while(rear!=front){//出队,打印出队结点的值 front++;printf("%d ",Queue[front]->data);//若有左孩子,左孩子进入队列 if(Queue[front]->lchild!=NULL){rear++;Queue[rear]=Queue[front]->lchild;}//若有右孩子,右孩子进入队列 if(Queue[front]->rchild!=NULL){rear++;Queue[rear]=Queue[front]->rchild;}}
}//删除排序二叉树, root为指向二叉树根结点的指针
void DestroyBST(BSTree root)
{if(root!=NULL){PreOrderCleanFlag(root->lchild);PreOrderCleanFlag(root->rchild);free(root);}
}//在根指针root所指二叉排序树root上,查找关键字等于data的结点,若查找成功,返回指向该元素结点指针,否则返回空指针
BSTree SearchBST(BSTree root,DataType data)
{ BSTree q;q=root;while(q){q->flag=1;if(q->data==data){q->flag=2;return q;        }if(q->data>data) q=q->lchild;else q=q->rchild;}return NULL;
}//在二叉排序树root中删去关键字为value的结点
BSTree DeleteBST(BSTree root,DataType value)
{BSTNode *p,*f,*s,*q;p=root; f=NULL;//查找关键字为value的待删结点pwhile(p){//找到则跳出循环,f指向p结点的双亲结点if(p->data==value) break;f=p;if(p->data>value) p=p->lchild;else p=p->rchild;}//若找不到,返回原来的二叉排序树if(p==NULL)  return root;//若p无左子树if(p->lchild==NULL){ if(f==NULL) root=p->rchild;else {if(f->lchild==p) f->lchild=p->rchild;else f->rchild=p->rchild;//释放被删除的结点pfree(p);}}//若p有左子树else{ q=p; s=p->lchild;while(s->rchild){q=s; s=s->rchild;}if(q==p) q->lchild=s->lchild;else q->rchild=s->lchild;p->data=s->data;free(s);}return root;
}//在根指针root所指二叉排序树中交换左右子树
void Exchange(BSTree root)
{if(root==NULL) return;if(root->lchild==NULL && root->rchild==NULL) return;BSTree temp=root->lchild;root->lchild=root->rchild;root->rchild=temp;Exchange(root->lchild);Exchange(root->rchild);
}//在根指针root所指二叉排序树中求树的深度
int Depth(BSTree root)
{if(root==NULL) return 0;return 1+max(Depth(root->lchild),Depth(root->rchild));
}int max(int a,int b)
{if (a>b) return a;return b;
}//在根指针root所指二叉排序树中计算总结点个数
int CountBiNode(BSTree root)
{if(root==NULL) return 0;int left=CountBiNode(root->lchild);int right=CountBiNode(root->rchild);return left+right+1;
}//根指针root所指二叉排序树中计算叶子结点个数
int CountLeaf(BSTree root)
{if(root==NULL) return 0;if(root->rchild==NULL && root->lchild==NULL) return 1;return (CountLeaf(root->lchild)+CountLeaf(root->rchild));
}void DotOrderList(BSTree root,FILE *fp)
{if(root==NULL)return;char lpoint=root->lchild ? ' ' : ' ';char rpoint=root->rchild ? ' ' : ' ';if(root->flag==1){fprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\",color=green];\n",root->data,lpoint,root->data,rpoint);}else if(root->flag==2){fprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\",color=red,fontcolor=red];\n",root->data,lpoint,root->data,rpoint);}elsefprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\"];\n",root->data,lpoint,root->data,rpoint);DotOrderList(root->lchild,fp);DotOrderList(root->rchild,fp);
}void DotOrderLink(BSTree root,FILE *fp)
{if(root==NULL)return;if(root->lchild)fprintf(fp,"%d:l:sw -> %d:d;\n",root->data,root->lchild->data);if(root->rchild)fprintf(fp,"%d:r:se -> %d:d;\n",root->data,root->rchild->data);DotOrderLink(root->lchild,fp);DotOrderLink(root->rchild,fp);
}void MakeDot(BSTree root,char *tital=NULL)
{FILE *fp=fopen("bstree.gv","w+");fprintf(fp,"digraph BSTree {\n");if(tital != NULL){fprintf(fp,"labelloc = t; labeljust = l;\n");fprintf(fp,"label = \"%s\";\n",tital);      }fprintf(fp,"node [fontname = Verdana, color=navy, shape=record, height=.1];\n");fprintf(fp,"edge [fontname = Verdana, color=navy, style=solid];\n");DotOrderList(root,fp);DotOrderLink(root,fp);fprintf(fp,"}\n\n");fclose(fp);
}int main()
{BSTree root;CreateBST(&root,"./data.txt");MakeDot(root);PreOrderCleanFlag(root);system("dot.exe -Tpng bstree.gv -o bstree.png");printf("该二叉排序树的深度为: %d\n该二叉排序树的总结点数为: %d\n该二叉排序树的叶子结点数为: %d\n中序遍历的结果为:\n",Depth(root),CountBiNode(root),CountLeaf(root));InOrder(root);SearchBST(root,62);MakeDot(root);system("dot.exe -Tpng bstree.gv -o bstree_search(62).png");PreOrderCleanFlag(root);SearchBST(root,98); MakeDot(root);system("dot.exe -Tpng bstree.gv -o bstree_search(98).png");PreOrderCleanFlag(root);DeleteBST(root,822);MakeDot(root);system("dot.exe -Tpng bstree.gv -o bstree_delete(822).png");DestroyBST(root);return 0;
}

AVLTree

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;#define MaxSize 100typedef int DataType;typedef struct node
{DataType data;int bf;int flag;struct node *lchild,*rchild;
}AVLNode,*AVLTree;//初始化一个平衡二叉树结点
AVLTree InitNode(DataType data)
{AVLTree Node=(AVLTree)malloc(sizeof(AVLNode));Node->data=data;Node->lchild=NULL;Node->rchild=NULL;Node->bf=0;Node->flag=0;
}//在平衡二叉树中插入值为data的元素,使之成为一棵新的平衡二叉排序树
void InsertAVL(AVLTree *root,DataType data)
{AVLNode *s;AVLNode *a,*fa,*p,*fp,*b,*c;s=InitNode(data);if(*root==NULL) *root=s;else { //首先查找S的插入位置fp,同时记录距S的插入位置最近且平衡因子不等于0(等于-1或1)的结点A,A为可能的失衡结点a=*root; fa=NULL;p=*root; fp=NULL;while(p!=NULL){ if(p->bf!=0) {a=p;fa=fp;}fp=p;if (data<p->data) p=p->lchild;else if(data>p->data) p=p->rchild;else{free(s);return;         }}//插入Sif(data<fp->data) fp->lchild=s;else fp->rchild=s;//确定结点B,并修改A的平衡因子if (data<a->data){b=a->lchild;a->bf=a->bf+1;}else{b=a->rchild;a->bf=a->bf-1;}//修改B到S路径上各结点的平衡因子(原值均为0)p=b;while(p!=s)if(data<p->data){p->bf=1;p=p->lchild;}else{p->bf=-1;p=p->rchild;}//判断失衡类型并做相应处理if(a->bf==2 && b->bf==1)       /* LL型 */{b=a->lchild;a->lchild=b->rchild;b->rchild=a;a->bf=0;b->bf=0;if(fa==NULL) *root=b;else {if(a==fa->lchild) fa->lchild=b;else fa->rchild=b;}}else if(a->bf==2 && b->bf==-1)       /* LR型 */{b=a->lchild;c=b->rchild;b->rchild=c->lchild;a->lchild=c->rchild;c->lchild=b;c->rchild=a;if(s->data<c->data){ a->bf=-1;b->bf=0;c->bf=0;}else if(s->data>c->data){a->bf=0;b->bf=1;c->bf=0;}else{ a->bf=0;b->bf=0;}if(fa==NULL) *root=c;else if(a==fa->lchild) fa->lchild=c;else fa->rchild=c;}else if(a->bf==-2 && b->bf==1)       /* RL型 */{b=a->rchild;c=b->lchild;b->lchild=c->rchild;a->rchild=c->lchild;c->lchild=a;c->rchild=b;if(s->data<c->data) { a->bf=0;b->bf=-1;c->bf=0;}else if(s->data>c->data){a->bf=1;b->bf=0;c->bf=0;}else { a->bf=0;b->bf=0;}if (fa==NULL) *root=c;else if(a==fa->lchild) fa->lchild=c;else fa->rchild=c;}else if(a->bf==-2 && b->bf==-1)       /* RR型 */{b=a->rchild;a->rchild=b->lchild;b->lchild=a;a->bf=0;b->bf=0;if(fa==NULL) *root=b;else if(a==fa->lchild) fa->lchild=b;else fa->rchild=b;}}
}//在平衡二叉树root中删去关键字为value的结点
AVLTree DeleteAVL(AVLTree root,DataType value)
{AVLNode *p,*f,*s,*q;p=root; f=NULL;//查找关键字为value的待删结点pwhile(p){//找到则跳出循环,f指向p结点的双亲结点if(p->data==value) break;f=p;if(p->data>value) p=p->lchild;else p=p->rchild;}//若找不到,返回原来的平衡二叉树if(p==NULL)  return root;//若p无左子树if(p->lchild==NULL){ if(f==NULL) root=p->rchild;else {if(f->lchild==p) f->lchild=p->rchild;else f->rchild=p->rchild;//释放被删除的结点pfree(p);}}//若p有左子树else{ q=p; s=p->lchild;while(s->rchild){q=s; s=s->rchild;}if(q==p) q->lchild=s->lchild;else q->rchild=s->lchild;p->data=s->data;free(s);}return root;
}//从文件输入元素的值,创建相应的平衡二叉树
void CreateAVL(AVLTree *root,const char *filename)
{ FILE *fp;DataType keynumber;*root=NULL;fp=fopen(filename,"r+");while(EOF!=fscanf(fp,"%d",&keynumber)) InsertAVL(root,keynumber);
}//先序遍历二叉树, root为指向二叉树根结点的指针
void PreOrderCleanFlag(AVLTree root)
{if(root!=NULL){//printf("%d(%d)\t",root->data,root->bf);root->flag=0;PreOrderCleanFlag(root->lchild);PreOrderCleanFlag(root->rchild);}
}//中序遍历二叉树, root为指向二叉树根结点的指针
void InOrder(AVLTree root)
{if(root!=NULL){InOrder(root->lchild);printf("%d ",root->data);InOrder(root->rchild);}
}//后序遍历二叉树, root为指向二叉树根结点的指针
void PostOrder(AVLTree root)
{if(root!=NULL){PostOrder(root->lchild);PostOrder(root->rchild);printf("%d ",root->data);}
}//层序遍历, root为指向二叉树根结点的指针
void LevelOrder(AVLTree root)
{//定义一个队列 AVLTree Queue[MaxSize];int front=-1,rear=0;// 若二叉树为空,遍历结束 if(root==NULL) return;//根结点进入队列 Queue[rear]=root;//若队列不为空,遍历,否则,遍历结束 while(rear!=front){//出队,打印出队结点的值 front++;printf("%d ",Queue[front]->data);//若有左孩子,左孩子进入队列 if(Queue[front]->lchild!=NULL){rear++;Queue[rear]=Queue[front]->lchild;}//若有右孩子,右孩子进入队列 if(Queue[front]->rchild!=NULL){rear++;Queue[rear]=Queue[front]->rchild;}}
}//删除平衡二叉树, root为指向二叉树根结点的指针
void DestroyAVL(AVLTree root)
{if(root!=NULL){PreOrderCleanFlag(root->lchild);PreOrderCleanFlag(root->rchild);free(root);}
}//在根指针root所指平衡二叉树root上,查找关键字等于data的结点,若查找成功,返回指向该元素结点指针,否则返回空指针
AVLTree SearchAVL(AVLTree root,DataType data)
{ AVLTree q;q=root;while(q){q->flag=1;if(q->data==data){q->flag=2;return q;       }if(q->data>data) q=q->lchild;else q=q->rchild;}return NULL;
}//在根指针root所指平衡二叉树中交换左右子树
void Exchange(AVLTree root)
{if(root==NULL) return;if(root->lchild==NULL && root->rchild==NULL) return;AVLTree temp=root->lchild;root->lchild=root->rchild;root->rchild=temp;Exchange(root->lchild);Exchange(root->rchild);
}//在根指针root所指平衡二叉树中求树的深度
int Depth(AVLTree root)
{if(root==NULL) return 0;return 1+max(Depth(root->lchild),Depth(root->rchild));
}int max(int a,int b)
{if (a>b) return a;return b;
}//在根指针root所指平衡二叉树中计算总结点个数
int CountBiNode(AVLTree root)
{if(root==NULL) return 0;int left=CountBiNode(root->lchild);int right=CountBiNode(root->rchild);return left+right+1;
}//根指针root所指平衡二叉树中计算叶子结点个数
int CountLeaf(AVLTree root)
{if(root==NULL) return 0;if(root->rchild==NULL && root->lchild==NULL) return 1;return (CountLeaf(root->lchild)+CountLeaf(root->rchild));
}void DotOrderList(AVLTree root,FILE *fp)
{if(root==NULL)return;char lpoint=root->lchild ? ' ' : ' ';char rpoint=root->rchild ? ' ' : ' ';if(root->flag==1){fprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\",color=green];\n",root->data,lpoint,root->data,rpoint);}else if(root->flag==2){fprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\",color=red,fontcolor=red];\n",root->data,lpoint,root->data,rpoint);}elsefprintf(fp,"%d[label = \"<l>%c|<d>%d|<r>%c\"];\n",root->data,lpoint,root->data,rpoint);DotOrderList(root->lchild,fp);DotOrderList(root->rchild,fp);
}void DotOrderLink(AVLTree root,FILE *fp)
{if(root==NULL)return;if(root->lchild)fprintf(fp,"%d:l:sw -> %d:d;\n",root->data,root->lchild->data);if(root->rchild)fprintf(fp,"%d:r:se -> %d:d;\n",root->data,root->rchild->data);DotOrderLink(root->lchild,fp);DotOrderLink(root->rchild,fp);
}void MakeDot(AVLTree root,char *tital=NULL)
{FILE *fp=fopen("avltree.gv","w+");fprintf(fp,"digraph BSTree {\n");if(tital != NULL){fprintf(fp,"labelloc = t; labeljust = l;\n");fprintf(fp,"label = \"%s\";\n",tital);     }fprintf(fp,"node [fontname = Verdana, color=navy, shape=record, height=.1];\n");fprintf(fp,"edge [fontname = Verdana, color=navy, style=solid];\n");DotOrderList(root,fp);DotOrderLink(root,fp);fprintf(fp,"}\n\n");fclose(fp);
}int main()
{AVLTree root;CreateAVL(&root,"./data.txt");MakeDot(root);PreOrderCleanFlag(root);system("dot.exe -Tpng avltree.gv -o avltree.png");printf("该平衡二叉树的深度为: %d\n该平衡二叉树的总结点数为: %d\n该平衡二叉树的叶子结点数为: %d\n中序遍历的结果为:\n",Depth(root),CountBiNode(root),CountLeaf(root));InOrder(root);SearchAVL(root,709);MakeDot(root);system("dot.exe -Tpng avltree.gv -o avltree_search(709).png");PreOrderCleanFlag(root);SearchAVL(root,98); MakeDot(root);system("dot.exe -Tpng avltree.gv -o avltree_search(98).png");PreOrderCleanFlag(root);DeleteAVL(root,340);MakeDot(root);system("dot.exe -Tpng avltree.gv -o avltree_delete(340).png");DestroyAVL(root);return 0;
}

Top-K problem

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<time.h>
using namespace std;typedef int DataType;#define TOTALNUM 200char figlabel[TOTALNUM];
char orderstr[TOTALNUM];
int heap[TOTALNUM];
int nNum,HeapSize;//交换函数
void swap(int *a,int *b)
{*a=*a+*b;*b=*a-*b;*a=*a-*b;
}//堆遍历
void HeapTraverse(int a[],int size)
{for(int i=0;i<size;i++) printf("%d ",a[i]);printf("\n");
}//带起始点的堆调整
void HeapShift(int a[],int size,int start)
{int dad=start,son=2*dad+1;while(son<=size){// 找子结点的最大值if(son+1<=size && a[son]>a[son+1]) son++;if(a[dad]<a[son]) return;else{swap(&a[dad],&a[son]);dad=son;son=2*dad+1;}}
}//堆排序
void HeapSort(int a[],int size)
{//构建初始堆for(int i=size/2-1;i>=0;i--){HeapShift(a,size-1,i);}for(int j=size-1;j>0;j--){// 堆顶元素和堆中的最后一个元素交换swap(&a[0],&a[j]);// 重新调整结构,使其继续满足堆定义HeapShift(a,j-1,0);}
}//堆调整
void HeapAdjust(int a[],int i,int size)
{int child;int temp;for(;2*i+1<size;i=child){child=2*i+1;if(child<size-1 && a[child+1]<a[child]) child++;if(a[i]>a[child]){temp=a[i];a[i]=a[child];a[child]=temp;}else break;}
}void DotHeap(int heap[],int n,char *label,int input=-1,int drop=-1)
{FILE *fpTree=fopen("heapT.gv","w+");fprintf(fpTree,"digraph heapT {\n");fprintf(fpTree,"fontname = \"Microsoft YaHei\"; labelloc = t; labeljust = l; rankdir = TB;\n");fprintf(fpTree,"label = \"%s\";\n",label);fprintf(fpTree,"node [fontname = \"Microsoft YaHei\", color=darkgreen, shape=circle, height=.1];\n");fprintf(fpTree,"edge [fontname = \"Microsoft YaHei\", color=darkgreen, style=solid, arrowsize=0.7];\n");    if(input!=-1 && drop!=-1){fprintf(fpTree,"in%d[label=\"%d\",shape=Mcircle,fontcolor=blue,color=blue];\n",input,input);}for(int i=0;i<n;i++){fprintf(fpTree,"%d[label=\"%d\"];\n",heap[i],heap[i]);}if(input!=-1 && drop!=-1 && input!=drop){fprintf(fpTree,"%d[label=\"%d\",shape=circle,fontcolor=blue,color=blue];\n",input,input);}if(input!=-1 && drop!=-1){if(input==drop){fprintf(fpTree,"%d[label=\"%d\",shape=doublecircle,fontcolor=darkgreen,color=darkgreen];\n",heap[0],heap[0]);}}if(input!=-1 && drop!=-1){if(input!=drop){fprintf(fpTree,"dp%d[label=\"%d\",shape=doublecircle,fontcolor=red,color=red];\n",drop,drop);}else{fprintf(fpTree,"dp%d[label=\"%d\",shape=Mcircle,fontcolor=red,color=red];\n",drop,drop);}}if(input!=-1 && drop!=-1){fprintf(fpTree,"{rank = same; in%d; %d; dp%d;};\n",input,heap[0],drop);fprintf(fpTree,"in%d -> %d[color=blue];\n",input,heap[0]);fprintf(fpTree,"%d -> dp%d[color=red];\n",heap[0],drop);}for(int i=0;i<n;i++){if(2*(i+1)-1<n) fprintf(fpTree,"%d:sw -> %d;\n",heap[i],heap[2*(i+1)-1]);if(2*(i+1)<n) fprintf(fpTree,"%d:se -> %d;\n",heap[i],heap[2*(i+1)]);}fprintf(fpTree,"node [fontname = \"Microsoft YaHei\", color=darkgreen, shape=record, height=.1];\n");fprintf(fpTree,"edge [fontname = \"Microsoft YaHei\", color=darkgreen, style=solid];\n");fprintf(fpTree,"struct [ label = \"{value|address} |");fprintf(fpTree,"{|%d} ",0);for(int i=0;i<n;i++){fprintf(fpTree,"| {%d|%d} ",heap[i],i+1);}fprintf(fpTree,"\"]; \n");fprintf(fpTree,"%d -> struct[color=white]; \n",heap[n-1]);fprintf(fpTree,"}\n\n");fclose(fpTree);
}int main()
{double start,finish;start=clock();nNum=0;HeapSize=10;memset(heap,'\0',sizeof(heap));FILE *fp;fp=fopen("./data.txt","r+");while(nNum<HeapSize && EOF!=fscanf(fp,"%d",&heap[nNum++]));sprintf(figlabel,"Initial Heap");DotHeap(heap,nNum,figlabel);sprintf(orderstr,"dot.exe -Tpng heapT.gv -o IniT.png");system(orderstr);for(int i=nNum/2;i>=0;i--){HeapAdjust(heap,i,nNum);}sprintf(figlabel,"Adjust Heap");DotHeap(heap,nNum,figlabel);sprintf(orderstr,"dot.exe -Tpng heapT.gv -o AdjT.png");system(orderstr);int temp;int k=11;while(EOF!=fscanf(fp,"%d",&temp)){sprintf(figlabel,"Input %d Drop %d",temp);if(temp>heap[0]){int pretop=heap[0];heap[0]=temp;HeapAdjust(heap,0,nNum);sprintf(figlabel,"Time = %d",k);DotHeap(heap,nNum,figlabel,temp,pretop);         }else{sprintf(figlabel,"Time = %d",k);DotHeap(heap,nNum,figlabel,temp,temp); }sprintf(orderstr,"dot.exe -Tpng heapT.gv -o Tree%02d.png",k++);system(orderstr);}sprintf(figlabel,"Current Heap Situation");DotHeap(heap,nNum,figlabel,temp);sprintf(orderstr,"dot.exe -Tpng heapT.gv -o FinaT.png");system(orderstr);finish=clock();printf("本次运行耗时: %f s\n",(finish-start)/CLOCKS_PER_SEC);return 0;
}

Dijkstra

#include<iostream>
#include<stack>
#include<fstream>using namespace std;typedef struct node
{int **edges;//邻接矩阵int n;//顶点数int e;//边数
}Graph;//初始化图
Graph CreateGraph(int n,int e)
{Graph graph;graph.n=n;graph.e=e;graph.edges=(int **)malloc(sizeof(int *)*graph.n);for(int i=0;i<graph.n;i++){graph.edges[i]=(int *)malloc(sizeof(int)*graph.n);}for(int i=0;i<graph.n;i++){for(int j=0;j<graph.n;j++){graph.edges[i][j]=0;}}return graph;
}//初始化dist
int *CreateDist(int size)
{int *dist=new int[size];return dist;
}//初始化path
int *CreatePath(int size)
{int *path=new int[size];return path;
}//初始化visited
bool *CreateVisited(int size)
{bool *visited=(bool *)malloc(sizeof(bool)*size);return visited;
}//释放邻接矩阵空间
void FreeGraph(Graph g)
{for(int i=0;i<g.n;i++){free(g.edges[i]);}free(g.edges);
}void DijkstraDot(Graph g,int *path,bool *visited,int vs)
{FILE *fp=fopen("dijkstra.gv","w+");fprintf(fp,"digraph Dijkstra {\nnode [shape=ellipse];\n");fprintf(fp,"v%d[shape=diamond,color=red,fontcolor=red];\n",vs);for(int i=0;i<g.n && i!=vs;i++){fprintf(fp,"v%d;\n",i);}for(int i=0;i<g.n;i++)  {  for(int j=0;j<g.n;j++)  {  if(g.edges[i][j]){if(visited[i] && visited[j] && path[j]==i){fprintf(fp,"v%d[fontcolor=red,color=red];\n",i);fprintf(fp,"v%d[fontcolor=red,color=red];\n",j);fprintf(fp,"v%d->v%d[style=bold,label=%d,fontcolor=red,color=red];\n",i,j,g.edges[i][j]);}else{fprintf(fp,"v%d->v%d[style=bold,label=%d];\n",i,j,g.edges[i][j]);   }}}  } fprintf(fp,"}\n");fclose(fp);
}//vs表示源顶点
void DijkstraPath(Graph g,int *dist,int *path,int vs)
{bool *visited=CreateVisited(g.n);//初始化for(int i=0;i<g.n;i++){if(g.edges[vs][i]>0 && i!=vs){dist[i]=g.edges[vs][i];//path记录最短路径上从vs到i的前一个顶点path[i]=vs; }else{//若i不与vs直接相邻,则权值置为无穷大dist[i]=INT_MAX;path[i]=-1;}visited[i]=false;path[vs]=vs;dist[vs]=0;}FILE *fp=fopen("dijkstra.gv","w+");fprintf(fp,"digraph Dijkstra {\nnode [shape=ellipse];\n");fprintf(fp,"v%d[shape=diamond,color=red,fontcolor=red];\n",vs);for(int i=0;i<g.n && i!=vs;i++){fprintf(fp,"v%d; ",i);}for(int i=0;i<g.n;i++)  {  for(int j=0;j<g.n;j++)  {  if(g.edges[i][j]){fprintf(fp,"v%d->v%d[style=bold,label=%d];\n",i,j,g.edges[i][j]);}}  }fprintf(fp,"}\n");fclose(fp);system("sfdp.exe -Tpng dijkstra.gv -o DijkSetp01.png");visited[vs]=true;//循环扩展n-1次for(int i=1;i<g.n;i++) {int min=INT_MAX;int u;//寻找未被扩展的权值最小的顶点for(int j=0;j<g.n;j++){if(!visited[j] && dist[j]<min){min=dist[j];u=j;        }} visited[u]=true;//更新dist数组的值和路径的值for(int k=0;k<g.n;k++) {if(!visited[k] && g.edges[u][k]>0 && min+g.edges[u][k]<dist[k]){dist[k]=min+g.edges[u][k];path[k]=u; }}DijkstraDot(g,path,visited,vs);char orderstr[128];sprintf(orderstr,"sfdp.exe -Tpng dijkstra.gv -o DijkSetp%02d.png",i+1);system(orderstr);        }
}//打印源顶点vs到各结点的最短路径
void PrintPath(Graph g,int *dist,int *path,int vs)
{for(int i=0;i<g.n;i++){if(vs!=i){printf("v%d -> v%d, minDist: %d, path: v%d <- ",vs,i,dist[i],i);int temp=path[i];while(vs!=temp){printf("v%d <- ",temp);temp=path[temp];}printf("v%d",vs);printf("\n");}}
}//打印邻接矩阵
void PrintGraph(Graph g)
{for(int i=0;i<g.n;i++){for(int j=0;j<g.n;j++){printf("%2d ",g.edges[i][j]);}printf("\n");}
}int main(int argc,char *argv[])
{if(argc<3) return 0x01;Graph g=CreateGraph(atoi(argv[1]),atoi(argv[2]));int *dist=CreateDist(g.n);int *path=CreatePath(g.n);int maxsinglearch,edgeCounter;if(g.e>=g.n){maxsinglearch=g.n;for(int i=0;i<g.n;i++){g.edges[i][(i+1)%g.n]=g.n/2+rand()%maxsinglearch;}edgeCounter=g.n;        }else edgeCounter=0;maxsinglearch=g.n;while(edgeCounter<g.e){rand();int s=rand()%g.n;int t=rand()%g.n;//随机生成没有双向弧的有向图if( s!=t && !g.edges[s][t] && (g.e>3*g.n || !g.edges[t][s]))  {g.edges[s][t]=rand()%maxsinglearch;edgeCounter++;}}printf("随机生成的邻接矩阵:\n");PrintGraph(g);printf("\n");int vs=0;FILE *fp=fopen("DijkInitGraph.gv","w+");fprintf(fp,"digraph DijkInitGraph {\nnode [shape=ellipse];\n");fprintf(fp,"v%d[shape=diamond];\n",vs);for(int i=0;i<g.n && i!=vs;i++){fprintf(fp,"v%d; ",i);}for(int i=0;i<g.n;i++){for(int j=0;j<g.n;j++)  {if(g.edges[i][j]){fprintf(fp,"v%d->v%d[style=bold,label=%d];\n",i,j,g.edges[i][j]);}}}fprintf(fp,"}\n");fclose(fp);system("sfdp.exe -Tpng DijkInitGraph.gv -o DijkInitGraph.png");//0表示输入从0号节点开始 DijkstraPath(g,dist,path,vs);//打印源顶点vs到各结点的最短路径printf("源顶点v0到各结点的最短路径为: \n");PrintPath(g,dist,path,vs);printf("\n");//释放结点FreeGraph(g);return 0;
}

RandomData

用于生成实验所需的随机数,数据存储在data.txt中。

import random
numlist=list()
while len(numlist)<100:num=random.randint(1,999)numlist.append(num)count=1
f=open('./data.txt','w+')
for num in numlist:n=str(num)if count==10:f.write(n+'\n')count=1else:f.write(n+'        ')count+=1
f.close()

《数据结构与算法》之课程实验相关推荐

  1. 《数据库及其应用》之课程实验

    <数据库及其应用>之课程实验 题面 12道SQL题 附加题 代码地址 题面 customer(uID,uName) hotel(hotel_id,hotel_name) order(ord ...

  2. 计算机科学与技术专业《计算机网络原理》课程实验指导书,计算机科学导论,课程实验指导书解读.pdf...

    计算机科学导论 实验指导书 聊城大学计算机学院聊城大学计算机学院 聊城大学计算机学院聊城大学计算机学院 2010 年年 8 月月 年年 月月 <计算机科学导论>课程实验指导书 目 录 &l ...

  3. 《数据库原理与应用》实验一

    题目来源学校课后作业,禁商业用途,仅用于课业学习 <数据库原理与应用>实验一 一.实验目的及要求 1.掌握MySQL系统的数据库创建方式. 2.掌握MySQL系统的数据表的创建方式. 3. ...

  4. 《数据库原理与应用》实验二

    题目来源学校课后作业,禁商业用途,仅用于课业学习 <数据库原理与应用>实验二 一.实验目的及要求 1.掌握SQL查询语言的使用. 2.掌握SQL流程控制语句的使用. 3.要求独立完成,并记 ...

  5. 2022年11月华南师范大学自考本科-计算机信息管理课程实验—《数据库系统原理》实践题目

    <   计算机信息管理课程实验--数据库系统原理  >课程试卷 答卷提交说明: 在mysql环境下填写SQL命令完成以下实践的题目,并返回执行结果的截图,答卷的答题格式如下,包括三部分:题 ...

  6. 计算机文化教程实验基础知识,《计算机文化基础》课程实验教学大纲

    课程编号: 课程名称(中文):计算机应用基础 课程名称(英文):Computer Culture Fundation 课程类型:公共基础课 课程学时:50学时学分:实验总学时:30学时 适用专业:各专 ...

  7. 杨月江计算机导论答案,计算机导论课程实验教学大纲-计算机学院-华北科技学院.doc...

    计算机导论课程实验教学大纲-计算机学院-华北科技学院.doc 华 北 科 技 学 院 2010级 实验教学大纲 网络工程系 目 录 TOC \o "1-1" \h \z \u HY ...

  8. 大学计算机课实验,大学计算机课程实验教学平台的设计与实现

    摘要: 随着信息技术的发展,<大学计算机>作为通识教育的核心课程早已被列入公共必修课程.<大学计算机>课程本身的特点决定了实验教学是整个教学活动中十分重要的环节,实验教学设计要 ...

  9. 课程linux实验报告,Linux操作系统课程实验报告.doc

    Linux操作系统课程实验报告.doc Linux操作系统课程实验报告班级姓名学号指导老师田丽华完成时间2014年7月目录一.实验目的1二.实验要求1三.实验内容1[第一题]1[第二题]2[第三题]4 ...

  10. 大学计算机科学课程实验,全校非计算机专业计算机公共课《大学IT》课程实验教学大纲...

    <大学IT>课程实验教学大纲 课程代码:                      课程性质:基础课 课程名称:计算机文化基础        英文名称:The Basis of Compu ...

最新文章

  1. 5分钟让你懂得什么是容器技术?
  2. python下线程以及锁
  3. 【cocos2d-x】Lua中的table函数库
  4. php插件 pycharm_原来Pycharm中有这么多好用的插件|Pycharm精选插件
  5. [新手及懒人适用]轻松恢复误Ghost的硬盘
  6. mysql naivcat执行存储过程_mysql使用navicat编写调用存储过程
  7. 基本类型理解巩固及补码原理总结
  8. 京东向上海提供超1600万件米面粮油等民生商品
  9. 【印刷字符识别】基于matlab OCR印刷字母+数字识别【含Matlab源码 287期】
  10. 第二章-信源与信息熵(一)
  11. 动态IP和静态IP有什么区别
  12. 4 描述性统计量和统计图
  13. 【Flask】学习笔记 #12 —— JinJa2模板继承与引入
  14. 北京住房公积金联名卡查询使用
  15. 【kronecker积rao积,及其它矩阵运算的一些性质】
  16. 《ppt》word插入批注,修改作者
  17. WebRTC市场价值到2026年将达到550亿美元
  18. 计算机键盘上的基准键是哪两个键,键盘上的基准键分别是什么?
  19. php必须是汉字的 正则,php汉字正则表达式
  20. SQL server management studio 使用

热门文章

  1. JVM堆内存介绍、垃圾收集算法、垃圾回收器汇总
  2. 关于第一期SWTC社区开发者大赛赛果的公告
  3. vue停止指令_一个微小的Vue指令,当到达边缘时停止传播滚动
  4. 英辞流——坚若金刚与穿行无碍:物质的三态
  5. 如何绘制motif结构图
  6. 【学习笔记】云服务器入门教程(搭建云盘、网站,安装anaconda、WinSCP、宝塔面板等)
  7. 由硫化铅/硒化物和碲化物(PbX:PbS,PbSe和PbTe)制成的QD钙钛矿量子点
  8. IEAD中运行代码,出现找不到或无法加载主类
  9. 数据可视化--Superset使用示例
  10. java oca_OCA - Java Test SE8 1Z0-808