电子科技大学《数据结构与算法》课程的3个实验,这里只展示代码,想要运行还得要对应的数据,用txt文件才能在命令行窗口调用运行。
#include
#include
#include
#include
using namespace std;
#define MaxSize 100
typedef 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的待删结点p
while(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;
//释放被删除的结点p
free(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 = \"%c|%d|%c\",color=green];\n" ,root->data,lpoint,root->data,rpoint);
}
else if(root->flag==2)
{
fprintf(fp,"%d[label = \"%c|%d|%c\",color=red,fontcolor=red];\n" ,root->data,lpoint,root->data,rpoint);
}
else
fprintf(fp,"%d[label = \"%c|%d|%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;
}
#include
#include
#include
using namespace std;
#define MaxSize 100
typedef 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;
}
}
//插入S
if(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的待删结点p
while(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;
//释放被删除的结点p
free(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 = \"%c|%d|%c\",color=green];\n" ,root->data,lpoint,root->data,rpoint);
}
else if(root->flag==2)
{
fprintf(fp,"%d[label = \"%c|%d|%c\",color=red,fontcolor=red];\n" ,root->data,lpoint,root->data,rpoint);
}
else
fprintf(fp,"%d[label = \"%c|%d|%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;
}
#include
#include
#include
#include
#include
using namespace std;
typedef int DataType;
#define TOTALNUM 200
char 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;
}
#include
#include
#include
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;
}
用于生成实验所需的随机数,数据存储在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=1
else:
f.write(n+' ')
count+=1
f.close()