11/18日作业

无向图带权值
代码:
#include<stdio.h>
#include<stdlib.h>
struct VNODE{
int value;
int quan;
VNODE *pRight;
VNODE *pNext;
};
void display(VNODE *root){
printf(“如下:\n”);
VNODE node1=(VNODE)malloc(sizeof(VNODE));
VNODE node3=(VNODE)malloc(sizeof(VNODE));
node1=root;
while(node1!=NULL){
printf("%d-",node1->value);
node3=node1;
while(node3->pRight!=NULL){
printf("(%d)",node3->pRight->quan);
printf("%d-",node3->pRight->value);
node3=node3->pRight;
}
printf("\n");
node1=node1->pNext;
}
}
int main(){
VNODE *root = NULL;
VNODE *tail = NULL;
int inputValue;
int quanzhong;
printf(“请输入顶点,以数字0结束:\n”);
scanf("%d",&inputValue);
while(inputValue!=0){
//生成顶点
VNODE node=(VNODE)malloc(sizeof(VNODE));
node->value=inputValue;
node->pRight=NULL;
node->pNext=NULL;
if(rootNULL){
root=node;
tail=node;
}
if(root!=NULL){
tail->pNext=node;
tail=node;
}
printf(“请输入顶点,以数字0结束:\n”);
scanf("%d",&inputValue);
if(inputValue
0)
{
break;
}
}

//输出
display(root);
//每一个顶点所指
tail=root;
while(tail!=NULL)
{
printf(“请输入%d的有向边指向的权和顶点,无向图不考虑方向,所以只要相邻就存入右节点,权值存入括号,以数字0结束:\n”,tail->value);
scanf("%d",&quanzhong);
scanf("%d",&inputValue);
VNODE *rTail = NULL;
while(inputValue!=0){
VNODE rnode=(VNODE)malloc(sizeof(VNODE));
rnode->value=inputValue;
rnode->quan=quanzhong;
rnode->pRight=NULL;
if(tail->pRight==NULL){
tail->pRight=rnode;
rTail=rnode;
}else{
rTail->pRight=rnode;
rTail=rnode;
}

	printf("请输入权重和顶点,以数字0结束:\n");
	scanf("%d",&quanzhong);
	scanf("%d",&inputValue);
	if(inputValue==0)
	{
		break;
	 } 
	}
	tail=tail->pNext;
 }
 //打印无向图 
 display(root);
 //prim

}
运行结果:

不完全二叉树
代码;
#include <stdio.h>
#include <stdlib.h>

struct TNODE{
int value;
TNODE *leftPointer;
TNODE *rightPointer;
};

//队列用的节点
struct QNODE{
TNODE *value;
QNODE *pNext;
};

//树的根节点指针
TNODE *root = NULL;

//队列的头和尾部
QNODE *head = NULL;
QNODE *tail = NULL;
QNODE *head1 = NULL;
QNODE tail1 = NULL;
void addToQueue(TNODE
node){
QNODE qNode = (QNODE)malloc(sizeof(QNODE));
qNode->value = node;
qNode->pNext = NULL;

if (head == NULL){
	head = qNode;
	tail = qNode;	
}else{
	tail->pNext = qNode;
	tail = qNode;
}

}
void addToStack(TNODE* node){
QNODE qNode = (QNODE)malloc(sizeof(QNODE));
qNode->value = node;
qNode->pNext = NULL;

if (head1 == NULL){
	head1 = qNode;
	tail1 = qNode;	
}else{
	qNode->pNext=head1;
	head1=qNode;
}

}

void displayAllDataInQueue(){
QNODE* p = head;
while(p != NULL){
TNODE* node = p->value;

	printf("%d\n", node->value);
	
	p = p->pNext;
}

}

//从队列头部弹出一个节点
QNODE* queuePop(){
QNODE* headNODE = head;
head = head->pNext;
if (head == NULL){
tail = NULL;
}

return headNODE;

}
//栈弹出
QNODE* stackPop(){
QNODE* headNODE = head1;
head1 = head1->pNext;
if (head1 == NULL){
tail1 = NULL;
}

return headNODE;

}
void displayAllDataInTree(){
if (root == NULL)
return;

head = NULL;
tail = NULL;	
	
//把root加到队列
addToQueue(root);

while (head != NULL){
	//取出队列的头结点
	QNODE *headNode = queuePop();
	//打印其值
	TNODE *tempNode = headNode->value;
	printf("%d\n", tempNode->value);
	
	//判断其左子节点是否存在,若存在,加入队列;
	if (tempNode->leftPointer != NULL){
		addToQueue(tempNode->leftPointer);
	}		
	
	//判断其右子节点是否存在,若存在,加入队列; 
	if (tempNode->rightPointer != NULL){
		addToQueue(tempNode->rightPointer);
	}
} 

}

//删除

void deletenum()
{
if(root==NULL)
{
return;
}
QNODE* node9=stackPop();
TNODE* node0=node9->value;
head = NULL;
tail = NULL;//把对列清空

//把root加到队列
addToQueue(root);
while (head != NULL){
	//取出队列的头结点
	QNODE *headNode = queuePop();
	//打印其值
	TNODE *tempNode = headNode->value;
	
	//判断其左子节点是否存在,若存在,加入队列;
	if (tempNode->leftPointer != NULL){
		addToQueue(tempNode->leftPointer);
	}		
	
	//判断其右子节点是否存在,若存在,加入队列; 
	if (tempNode->rightPointer != NULL){
		addToQueue(tempNode->rightPointer);
	}
	if(tempNode->leftPointer->value==node0->value)
	{
		tempNode->leftPointer=NULL;
		free(node0);
		break;
	}
	if(tempNode->rightPointer->value==node0->value)
	{
		tempNode->rightPointer=NULL;
		free(node0);
		break;
	}
	
} 

}
int main(){

TNODE* node = (TNODE*)malloc(sizeof(TNODE));
node->value = 1;
node->leftPointer = NULL;
node->rightPointer = NULL;
root = node; 

//将其加入到队列中
addToQueue(node);	
addToStack(node);
while(head != NULL){
	//取出来队列的头结点
	QNODE *headNode = queuePop(); 
	
	printf("请输入新左子节点的值:");
	int temp1;
	scanf("%d", &temp1);
	if (temp1 == 0){
		break;
	}
	if(temp1==-1){
	TNODE* pLeftNode = (TNODE*)malloc(sizeof(TNODE));
	pLeftNode->value = NULL;
	pLeftNode->leftPointer = NULL;
	pLeftNode->rightPointer = NULL;		
	TNODE* topNode = headNode->value;
	topNode->leftPointer = pLeftNode;
	addToQueue(pLeftNode);
	addToStack(pLeftNode);
	} 
	else{
	TNODE* pLeftNode = (TNODE*)malloc(sizeof(TNODE));
	pLeftNode->value = temp1;
	pLeftNode->leftPointer = NULL;
	pLeftNode->rightPointer = NULL;		
	TNODE* topNode = headNode->value;
	topNode->leftPointer = pLeftNode;
	addToQueue(pLeftNode);
	addToStack(pLeftNode);
    }
	printf("请输入新右子节点的值:");
	int temp2;
	scanf("%d", &temp2);
	if (temp2 == 0){
		break;
	}
	if(temp2==-1){
	TNODE* pRightNode = (TNODE*)malloc(sizeof(TNODE));
	pRightNode->value = NULL;
	pRightNode->leftPointer = NULL;
	pRightNode->rightPointer = NULL;
	TNODE* topNode = headNode->value;				
	topNode->rightPointer = pRightNode;
	addToQueue(pRightNode);
	addToStack(pRightNode);	
	}
	else{
	TNODE* pRightNode = (TNODE*)malloc(sizeof(TNODE));
	pRightNode->value = temp2;
	pRightNode->leftPointer = NULL;
	pRightNode->rightPointer = NULL;		
	TNODE* topNode = headNode->value;
	topNode->rightPointer = pRightNode;
	addToQueue(pRightNode);
	addToStack(pRightNode);
    }
}

//testing queue	
//displayAllDataInQueue();

printf("以下为非完全二叉树的值:\n");
//testing tree
displayAllDataInTree();

//删除最后一个节点

deletenum();

//
printf("以下为非完全二叉树的值:\n");
//testing tree
displayAllDataInTree();


return 0;

}
运行结果:

3、prim
代码:
#include <stdio.h>
#include <stdlib.h>
#define VertexType int
#define VRType int
#define MAX_VERtEX_NUM 20
#define InfoType char
#define INFINITY 65535
typedef struct {
VRType adj; //对于无权图,用 1 或 0 表示是否相邻;对于带权图,直接为权值。
InfoType * info; //弧额外含有的信息指针
}ArcCell,AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM];
typedef struct {
VertexType vexs[MAX_VERtEX_NUM]; //存储图中顶点数据
AdjMatrix arcs; //二维数组,记录顶点之间的关系
int vexnum,arcnum; //记录图的顶点数和弧(边)数
}MGraph;
//根据顶点本身数据,判断出顶点在二维数组中的位置
int LocateVex(MGraph G,VertexType v){
int i=0;
//遍历一维数组,找到变量v
for (; i<G.vexnum; i++) {
if (G.vexs[i]v) {
return i;
}
}
return -1;
}
//构造无向网
void CreateUDN(MGraph* G){
scanf("%d,%d",&(G->vexnum),&(G->arcnum));
for (int i=0; ivexnum; i++) {
scanf("%d",&(G->vexs[i]));
}
for (int i=0; ivexnum; i++) {
for (int j=0; jvexnum; j++) {
G->arcs[i][j].adj=INFINITY;
G->arcs[i][j].info=NULL;
}
}
for (int i=0; iarcnum; i++) {
int v1,v2,w;
scanf("%d,%d,%d",&v1,&v2,&w);
int m=LocateVex(*G, v1);
int n=LocateVex(*G, v2);
if (m
-1 ||n==-1) {
printf(“no this vertex\n”);
return;
}
G->arcs[n][m].adj=w;
G->arcs[m][n].adj=w;
}
}
//辅助数组,用于每次筛选出权值最小的边的邻接点
typedef struct {
VertexType adjvex;//记录权值最小的边的起始点
VRType lowcost;//记录该边的权值
}closedge[MAX_VERtEX_NUM];
closedge theclose;//创建一个全局数组,因为每个函数中都会使用到
//在辅助数组中找出权值最小的边的数组下标,就可以间接找到此边的终点顶点。
int minimun(MGraph G,closedge close){
int min=INFINITY;
int min_i=-1;
for (int i=0; i<G.vexnum; i++) {
//权值为0,说明顶点已经归入最小生成树中;然后每次和min变量进行比较,最后找出最小的。
if (close[i].lowcost>0 && close[i].lowcost < min) {
min=close[i].lowcost;
min_i=i;
}
}
//返回最小权值所在的数组下标
return min_i;
}
//普里姆算法函数,G为无向网,u为在网中选择的任意顶点作为起始点
void miniSpanTreePrim(MGraph G,VertexType u){
//找到该起始点在顶点数组中的位置下标
int k=LocateVex(G, u);
//首先将与该起始点相关的所有边的信息:边的起始点和权值,存入辅助数组中相应的位置,例如(1,2)边,adjvex为0,lowcost为6,存入theclose[1]中,辅助数组的下标表示该边的顶点2
for (int i=0; i<G.vexnum; i++) {
if (i !=k) {
theclose[i].adjvex=k;
theclose[i].lowcost=G.arcs[k][i].adj;
}
}
//由于起始点已经归为最小生成树,所以辅助数组对应位置的权值为0,这样,遍历时就不会被选中
theclose[k].lowcost=0;
//选择下一个点,并更新辅助数组中的信息
for (int i=1; i<G.vexnum; i++) {
//找出权值最小的边所在数组下标
k=minimun(G, theclose);
//输出选择的路径
printf(“v%d v%d\n”,G.vexs[theclose[k].adjvex],G.vexs[k]);
//归入最小生成树的顶点的辅助数组中的权值设为0
theclose[k].lowcost=0;
//信息辅助数组中存储的信息,由于此时树中新加入了一个顶点,需要判断,由此顶点出发,到达其它各顶点的权值是否比之前记录的权值还要小,如果还小,则更新
for (int j=0; j<G.vexnum; j++) {
if (G.arcs[k][j].adj<theclose[j].lowcost) {
theclose[j].adjvex=k;
theclose[j].lowcost=G.arcs[k][j].adj;
}
}
}
printf("\n");
}
int main(){
MGraph G;
CreateUDN(&G);
miniSpanTreePrim(G, 1);
}

运行结果:
v1 v3
v3 v6
v6 v4
v3 v2
v2 v5/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值