今日做的两道题

20 篇文章 0 订阅
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <vector>
#include <time.h>
using namespace std;

//    定义链表中的节点
typedef struct node
{
	int age; //    节点中的成员
	int id;
	struct node *pNext;        //    指向下一个节点的指针
}Node, *pNode;

//    函数声明
pNode CreateList();                 //  创建链表函数
int TraverseList(pNode);            //  遍历链表函数
int TraverseListq(pNode,int);            //  遍历链表函数
bool Insert_Node(pNode, int, int, int);    //    链表节点插入函数,第一个参数是头节点,第二个参数是要在第几个节点前插入,第三个参数是要插入的数据
int Del_Node(pNode, int);        //    删除链表节点,第一个参数是头节点,第二个参数是删除第几个节点,第三个作为

int main()
{
	pNode pHead = NULL;                //  定义初始化头节点,等价于 struct Node *pHead == NULL
	int data;                        // 作为Insert_Node函数的第三个参数
	int num;                        //    作为Inset_Node函数第二个参数
	int return_val;
	pHead = CreateList();            //  创建一个非循环单链表,并将该链表的头结点的地址付给pHead
	printf("初始化的数据是:");

	for (int i = 0; i < 50; i++)
	{		
		int val = TraverseList(pHead);
		//cin >> val;
		while (val > 0)
		{
			num = val;
			//scanf_s("%d", &num);
			return_val = Del_Node(pHead, num);
			if (return_val == 0)
			{
				printf("删除失败。\n");
			}
			else
			{
				printf("删除成功。删除的元素是:%d\n", return_val);
			}
			val=TraverseList(pHead);
		}
		Insert_Node(pHead, 2, 1, i);
		TraverseListq(pHead, 1);
		cout << "第" << i << "次加入和删除完毕, 结果如下:\n";
		printf("操作完成后的数据是:");
	}
	TraverseList(pHead);
	return 0;
}

//    创建链表函数
pNode CreateList()
{
	int i;                                            //    用于下面循环
	int len;                                        //    用来存放有效节点的字数
	int val;                                        //    用于临时存放用户输入的数据
	pNode pHead = (pNode)malloc(sizeof(Node));        //  分配一个不存放有效数据的头结点
	pNode pTail = pHead;                            //    链表的最后一个节点
	pTail->pNext = NULL;                            //    最后一个节点的指针置为空
	/*printf("请输入节点个数:");
	scanf_s("%d", &len);*/
	len = 5;
	for (i = 0; i < len; i++)
	{
		val = rand() % (10 - 0 + 1) + 1;
		pNode pNew = (pNode)malloc(sizeof(Node));    //    为节点分配空间
		pNew->age = val;                            //将用户输入的数据赋给节点的成员
		pNew->id = i;
		pTail->pNext = pNew;                        //将最后一个节点的指针指向下一个新的节点
		pNew->pNext = NULL;                            //将新节点中的指针置为空
		pTail = pNew;                                //将新节点赋给最后的一个节点
	}
	return pHead;                                    //返回头节点

}

//    遍历链表函数
int TraverseList(pNode pHead)
{
	pNode p = pHead->pNext;
	//将头节点的指针给予临时节点p
	int i = 1;
	int val = 0;
	while (NULL != p)                                //节点p不为空,循环    
	{
		printf("(index=%d id=%d age=%d)", i, p->id, p->age);
		if (p->age >= 9)
			val = i;
		p = p->pNext;
		i++;
	}
	printf("\n");
	return val;
}

//    遍历链表函数
int TraverseListq(pNode pHead, int id=1)
{
	pNode p = pHead->pNext;
	//将头节点的指针给予临时节点p
	int i = 1;
	while (NULL != p)                                //节点p不为空,循环    
	{
		p->age = p->age + 1;
		p = p->pNext;
		i++;
	}
	printf("\n");
	return 0;
}

//    链表节点插入函数
//    第一个参数是头节点,第二个参数是要在第几个节点前插入,第三个参数是要插入的数据
bool Insert_Node(pNode pHead, int front, int data, int id)
{
	int i = 0;
	pNode _node = pHead;
	pNode pSwap;                                //    用于交换
	if ((front < 1) && (NULL != _node))        //判断用户输入的数据是否大于等于1,及_node是否为空
	{
		return false;
	}
	while (i < front - 1)                    //通过循环使指针指向要插入哪个节点前的节点。说的自己都不懂了,还是看下面的图吧。    
	{
		_node = _node->pNext;
		++i;
	}
	pNode pNew = (pNode)malloc(sizeof(Node));

	pNew->age = data;                        //    把输入的数据赋给要插入的节点
	pNew->id = id;
	pSwap = _node->pNext;                        //    把下一个节点的地址,给用于交换的pSwap
	_node->pNext = pNew;                        //    把要插入的节点的地址,给上个节点的指针域
	pNew->pNext = pSwap;                        //    把插入节点的下一个节点的地址,给插入节点的指针域
	return true;

}

//    删除链表节点函数
//    第一个参数是头节点,第二个参数是要删除第几个节点·······和上面的插入函数是不是很像
int Del_Node(pNode pHead, int back)
{
	int i = 0;
	int data;
	pNode _node = pHead;
	pNode pSwap;
	if ((back < 1) && (NULL == _node->pNext))
	{
		printf("删除失败!\n");
		return 0;
	}
	while (i < back - 1)
	{
		_node = _node->pNext;
		++i;
	}
	pSwap = _node->pNext;
	data = pSwap->age;
	_node->pNext = _node->pNext->pNext;
	free(pSwap);
	return data;
}

以上代码实现了求结点间的对短距离。


#include <stdafx.h>
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <iostream>

using namespace std;

#define MAX         100                 // 矩阵最大容量  
#define INF         65535               // 最大值65535  
#define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))  
#define LENGTH(a)   (sizeof(a)/sizeof(a[0]))  

// 图的邻接矩阵存储  
typedef struct _graph
{
	char vexs[MAX];       // 顶点集合  
	int vexnum;           // 顶点数  
	int edgnum;           // 边数  
	int matrix[MAX][MAX]; // 邻接矩阵  
}Graph, *PGraph;

// 边的结构体  
typedef struct _EdgeData
{
	char start; // 边的起点  
	char end;   // 边的终点  
	int weight; // 边的权重  
}EData;

/*
* 返回ch在matrix矩阵中的位置
*/
static int get_position(Graph G, char ch)
{
	int i;
	for (i = 0; i<G.vexnum; i++)
	if (G.vexs[i] == ch)
		return i;
	return -1;
}

/*
* 读取一个输入字符
*/
static char read_char()
{
	char ch;

	do {
		ch = getchar();
	} while (!isLetter(ch));

	return ch;
}

/*
* 创建图(用已提供的矩阵)  
*/
Graph* create_example_graph()
{
	char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
	int matrix[][9] = {
		/*A*//*B*//*C*//*D*//*E*//*F*//*G*/
		/*A*/{ 0, 12, INF, INF, INF, 16, 14 },
		/*B*/{ 12, 0, 10, INF, INF, 7, INF },
		/*C*/{ INF, 10, 0, 3, 5, 6, INF },
		/*D*/{ INF, INF, 3, 0, 4, INF, INF },
		/*E*/{ INF, INF, 5, 4, 0, 2, 8 },
		/*F*/{ 16, 7, 6, INF, 2, 0, 9 },
		/*G*/{ 14, INF, INF, INF, 8, 9, 0 } };
	int vlen = LENGTH(vexs);
	int i, j;
	Graph* pG;

	// 输入"顶点数"和"边数"  
	if ((pG = (Graph*)malloc(sizeof(Graph))) == NULL)
		return NULL;
	memset(pG, 0, sizeof(Graph));

	// 初始化"顶点数"  
	pG->vexnum = vlen;
	// 初始化"顶点"  
	for (i = 0; i < pG->vexnum; i++)
		pG->vexs[i] = vexs[i];

	// 初始化"边"  
	for (i = 0; i < pG->vexnum; i++)
	for (j = 0; j < pG->vexnum; j++)
		pG->matrix[i][j] = matrix[i][j];

	// 统计边的数目  
	for (i = 0; i < pG->vexnum; i++)
	for (j = 0; j < pG->vexnum; j++)
	if (i != j && pG->matrix[i][j] != INF)
		pG->edgnum++;
	pG->edgnum /= 2;

	return pG;
}

/*
* 返回顶点v的第一个邻接顶点的索引,失败则返回-1
*/
static int first_vertex(Graph G, int v)
{
	int i;

	if (v<0 || v>(G.vexnum - 1))
		return -1;

	for (i = 0; i < G.vexnum; i++)
	if (G.matrix[v][i] != 0 && G.matrix[v][i] != INF)
		return i;

	return -1;
}

/*
* 返回顶点v相对于w的下一个邻接顶点的索引,失败则返回-1
*/
static int next_vertix(Graph G, int v, int w)
{
	int i;

	if (v<0 || v>(G.vexnum - 1) || w<0 || w>(G.vexnum - 1))
		return -1;

	for (i = w + 1; i < G.vexnum; i++)
	if (G.matrix[v][i] != 0 && G.matrix[v][i] != INF)
		return i;

	return -1;
}

/*
* 深度优先搜索遍历图的递归实现
*/
static void DFS(Graph G, int i, int *visited)
{
	int w;

	visited[i] = 1;
	printf("%c ", G.vexs[i]);
	// 遍历该顶点的所有邻接顶点。若是没有访问过,那么继续往下走  
	for (w = first_vertex(G, i); w >= 0; w = next_vertix(G, i, w))
	{
		if (!visited[w])
			DFS(G, w, visited);
	}

}

/*
* 打印矩阵队列图//yyyy
*/
void print_graph(Graph G)
{
	int i, j;

	printf("Martix Graph:\n");
	for (i = 0; i < G.vexnum; i++)
	{
		for (j = 0; j < G.vexnum; j++)
			printf("%10d ", G.matrix[i][j]);
		printf("\n");
	}
}


/*
* 获取图中的边
*/
EData* get_edges(Graph G)
{
	int i, j;
	int index = 0;
	EData *edges;

	edges = (EData*)malloc(G.edgnum*sizeof(EData));
	for (i = 0; i < G.vexnum; i++)
	{
		for (j = i + 1; j < G.vexnum; j++)
		{
			if (G.matrix[i][j] != INF)
			{
				edges[index].start = G.vexs[i];
				edges[index].end = G.vexs[j];
				edges[index].weight = G.matrix[i][j];
				index++;
			}
		}
	}

	return edges;
}

/*
* 对边按照权值大小进行排序(由小到大)
*/
void sorted_edges(EData* edges, int elen)
{
	int i, j;

	for (i = 0; i<elen; i++)
	{
		for (j = i + 1; j<elen; j++)
		{
			if (edges[i].weight > edges[j].weight)
			{
				// 交换"第i条边"和"第j条边"  
				EData tmp = edges[i];
				edges[i] = edges[j];
				edges[j] = tmp;
			}
		}
	}
}

/*
* 获取i的终点
*/
int get_end(int vends[], int i)
{
	while (vends[i] != 0)
		i = vends[i];
	return i;
}

void dijkstra(Graph G, int vs, int vs2, int prev[], int dist[])
{
	int i, j, k;
	int min;
	int tmp;
	int flag[MAX];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。  

	// 初始化  
	for (i = 0; i < G.vexnum; i++)
	{
		flag[i] = 0;              // 顶点i的最短路径还没获取到。  
		prev[i] = 0;              // 顶点i的前驱顶点为0。  
		dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。  
	}

	// 对"顶点vs"自身进行初始化  
	flag[vs] = 1;
	dist[vs] = 0;

	// 遍历G.vexnum-1次;每次找出一个顶点的最短路径。  
	for (i = 1; i < G.vexnum; i++)
	{
		// 寻找当前最小的路径;  
		// 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。  
		min = INF;
		for (j = 0; j < G.vexnum; j++)
		{
			if (flag[j] == 0 && dist[j]<min)
			{
				min = dist[j];
				k = j;
			}
		}
		// 标记"顶点k"为已经获取到最短路径  
		flag[k] = 1;

		// 修正当前最短路径和前驱顶点  
		// 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。  
		for (j = 0; j < G.vexnum; j++)
		{
			tmp = (G.matrix[k][j] == INF ? INF : (min + G.matrix[k][j])); // 防止溢出  
			if (flag[j] == 0 && (tmp  < dist[j]))
			{
				dist[j] = tmp;
				prev[j] = k;
			}
		}
	}

	// 打印dijkstra最短路径的结果  
	printf("dijkstra(%c-->%c): \n", G.vexs[vs], G.vexs[vs2]);
	printf("  shortest(%c, %c)=%d\n", G.vexs[vs], G.vexs[vs2], dist[vs2]);
}

int main()
{
	int prev[MAX] = { 0 };
	int dist[MAX] = { 0 };
	Graph* pG;
	// 采用已有的"图"  
	pG = create_example_graph();
	print_graph(*pG);       // 打印图  
	int inNode1=3;
	int inNode2=6;
	printf("请输入两个顶点的数值(例如:1 2;3 6):\n ");
	printf("提示:请不要输入大于6的数字\n ");
	cin >> inNode1 >> inNode2;

	dijkstra(*pG, inNode1, inNode2, prev, dist);
	return 0;
}

以上代码实现了在特定要求下单向链表的删除与添加功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值