无向图带权值
代码:
#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(inputValue0)
{
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/