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

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

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

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

BSTree and AVLTree

BSTree

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

AVLTree

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

Top-K problem

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

Dijkstra

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

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=1
    else:
        f.write(n+'        ')
        count+=1
f.close()

你可能感兴趣的:(数据结构与算法,数据结构)