数据结构——单链表,栈,队列,二叉树,树,图 基础代码

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#define  MaxSize 100
#define  N 20
typedef  char VertexType;
typedef  int EdgeType;
typedef struct LNODE
{
	int data;
	struct LNODE * next;
}LNODE, *LinkList;					// definition of the LinkList
typedef struct StackNode
{
	int data;
	int top;
	int bottom;
}StackNode, *Stack;				// definition of the Stack
typedef struct CTNode
{
	int data;
	struct CTNode *lchild;
	struct CTNode *rchild;
}CTNode, *BiTree;					// definition of the CT tree      
typedef struct CSNode
{
	char data;
	struct CSNode* firstchild;
	struct CSNode* nextsibling;
}CSNode, *BinTree;				    // definition of the CS tree
typedef struct QueueNode
{
	BiTree *queue;   //一个将来用作数组名的指针变量queue
	int front;
	int rear;
}QueueNode, *MatrixQueue;       // definition of the queue 
typedef struct MGraph
{
	int vexnum, arcnum;//当前定点数和弧的数量
	VertexType Vex[N]; //存定点第一个数组
	EdgeType Edge[N][N]; //存边第一个数组
}MGraph;                           // Matrix Graph
typedef struct ArcNode  
{
	int adjvex;  //边对应节点的下标
	int weigth;  //用于存储权值                                   
	struct ArcNode * nextarc;  //链域,指向下一个邻接点 (边向顶点方向移动)
}ArcNode;                         //边表节点
typedef struct VNode
{
	VertexType data;   //存储顶点数据的信息
	ArcNode *firstarc;  //定点表对应边表的头指针  (顶点向边方向移动)
}VNode,AdjList[N];                  //顶点表节点
typedef struct ALGraph
{
	AdjList adjlist;
	int vexnum;
	int arcnum;
}ALGraph ,*AGraph;                //宏观定义邻接表的大节点类型
typedef struct 
{
	VertexType vex[N];
	EdgeType edge[N][N];
	int vexnum, arcnum;
}MarixGraph;

LinkList createlist();
bool traverse_list(LinkList);
int length_of_the_list(LinkList);
void insert_elem(LinkList, int);
void Bubble_sort_list(LinkList);
void dele_elem(LinkList);
MatrixQueue init_q(MatrixQueue);
bool IsEmpty_q(MatrixQueue);
bool IsFull_q(MatrixQueue);
void enqueue(MatrixQueue, BiTree);
BiTree dequeue(MatrixQueue, BiTree);
void traverse_q(MatrixQueue);
BiTree create_tree(BiTree);
void Pretraverse_tree(BiTree);
void Midtraverse_tree(BiTree);
void Postraverse_tree(BiTree);
void Leveltraverse_tree(BiTree);
void Levelorder_sealed(BiTree);
int getheight(BiTree);
int BT_depth1(BiTree,int);
int Height(BiTree);
void CreateAdjListGraph(AGraph);
void PrintAdjListGraph(AGraph);
bool visited[MaxSize];
void BFS(AGraph,int);
void DFS(AGraph, int);
void SelectSort(LinkList);
void selectsort(LinkList);
void HeapSort(LinkList);
void ShellSort(LinkList);
void GetLongestPath(BiTree T, char currentpath[], int &currentlength, char maxpath[], int &maxlength);
//main function content
void main()
{
	CTNode K;
	BiTree n = create_tree(&K); //这里有时候用直接空值变量会好点,有时候用取地址不报错
	//Pretraverse_tree(n); 
	//Midtraverse_tree(n); 
	//Postraverse_tree(n);
	//Leveltraverse_tree(n);
	//Levelorder_sealed(n);
	//int k=getheight(n);
	//printf("%d\n",k);
	//ALGraph G;
	//CreateAdjListGraph(&G);
	//PrintAdjListGraph(&G);
	//LinkList a = createlist();
	//selectsort(a);
	//printf("\n");
	//traverse_list(a);
	char currentpath[N], maxpath[N];
	int currentlength = 0, maxlength = 0;
	GetLongestPath(n, currentpath, currentlength, maxpath, maxlength);
	for (int i = 0; i <= maxlength; i++)
	{
		printf("%c ",maxpath[i]);
	}
	printf("\n");
}
//Linklist
LinkList createlist()
{
	LinkList L, T;
	int len, tmp;
	printf("请输入链表的长度:\n");
	scanf_s("%d", &len);
	L = (LinkList)malloc(sizeof(LNODE));//作为一个头动态游标;指针不停地动,指向需要的地方。
	T = L; //作为一个尾动态游标(尾指针T),精髓就在于这个尾巴是一个虚拟的尾巴,不是加在头结点后面的实体节点。
	T->next = NULL;
	for (int i = 1; i <= len; i++)
	{
		printf("请输入第%d个元素的值:\n", i);
		scanf_s("%d", &tmp);
		LinkList pBody = (LinkList)malloc(sizeof(LNODE));
		pBody->data = tmp;
		pBody->next = NULL;
		/* **********************************************************************************************************/
		T->next = pBody;// T->next:T访问它指向的当前节点的指针域的内容,指针域内容指向第二个节点。
		T = pBody;//新生成的节点当做现在的尾节点(新节点的地址发送到尾指针T中,这样T就可以继续指向新节点了)

				  /* **********************************************************************************************************/
	}  //尾游标增加过一个节点之后当然需要移动位置,从而继续增加第二个节点,移动位置就是新节点的地址赋值给尾游标。
	return L;
}   //《尾插法实现单链表的创建》 2018.7.24 
int length_of_the_list(LinkList K)
{
	int length = 0;
	LinkList cat = K->next;
	while (cat->next != NULL)//利用尾指针指向的那个元素的指针域为null来判断是否游到表尾
	{
		length++;
		cat = cat->next;//单链表顺序遍历的核心思想,从一个未知的虚拟地址空间cat开始,cat指向的那个不虚拟的实体里存放的下一个实体的地址
	}
	return length + 1;
}
void insert_elem(LinkList tiger, int m)
{
	int i = 0;
	LinkList snake = tiger->next; //遍历的时候要分情况
	LinkList pBody = (LinkList)malloc(sizeof(LNODE));
	pBody->data = 500;
	for (i; i < m - 1; ++i)
	{
		snake = snake->next;
	}
	pBody->next = snake->next;
	snake->next = pBody;
}
void dele_elem(LinkList lion)
{
	int n;
	LinkList fish = lion->next;
	LinkList tmp = (LinkList)malloc(sizeof(LNODE));
	printf("x后面的元素将被删除,请输入x:");
	scanf_s("%d", &n);
	for (int i = 0; i < n - 1; ++i)//假设要删除第一个元素后面的元素,那么一次都不需要循环,游标默认停留在第一个元素那,指向第一个元素。
	{
		fish = fish->next;
	}
	fish->next = fish->next->next;//单次覆盖即可达到目的。	把第三个节点的地址存放到第一个节点指针域中去就行了 

}
void Bubble_sort_list(LinkList panda)
{
	int i, j;
	int k = length_of_the_list(panda);
	LinkList bear = panda->next;
	LinkList bear1 = bear;
	LinkList eagle=(LNODE *)malloc(sizeof(LNODE));
	printf("冒泡排序过后的元素依次为:\n");
	for (i = 0; i < k; i++)
	{
		for (j = 0; j < k - 1; j++)
		{
			if (bear->data > bear->next->data)
			{
				eagle->data = bear->data;
				bear->data = bear->next->data;
				bear->next->data = eagle->data;
			}
			bear = bear->next;
		}
		bear = bear1;//从头开始计算,要不然bear游到了末尾就没法回头了
	}

}
bool traverse_list(LinkList head)
{
	LinkList p = head->next;
	while (p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	return true;
}
//Queue
MatrixQueue init_q(MatrixQueue m) //数组初始化
{
	m->queue = (BiTree *)malloc(sizeof(CTNode)*MaxSize);
	m->front = 0;
	m->rear = 0;
	return m;
}
bool IsFull_q(MatrixQueue s)
{
	if ((s->rear + 1) % MaxSize == s->front)
		return true;
	else
		return false;
}
bool IsEmpty_q(MatrixQueue m)
{
	if (m->rear == m->front)
		return true;
	else
		return false;
}
void enqueue(MatrixQueue c, BiTree val)
{
	if (!IsFull_q(c))
	{
		c->queue[c->rear] = val;
		c->rear = (c->rear + 1) % MaxSize;
	}
	else
		printf("enqueue failure! \n");
}
BiTree dequeue(MatrixQueue d, BiTree val)
{
	if (!IsEmpty_q(d))
	{
		val = d->queue[d->front];
		d->front = (d->front + 1) % MaxSize;
		return val;
	}
	else
	{
		printf("queue is full \n");
	}

}
void traverse_q(MatrixQueue k)
{
	int i = k->front;
	while (i != k->rear)
	{
		printf("%d\n", k->queue[i]);
		i = (i + 1) % MaxSize;
	}
}
//CT Binary Tree
BiTree create_tree(BiTree t)
{
	char ch;
	scanf_s("%c", &ch, sizeof(ch));
	if (ch == ' ')
	{
		t = NULL;
	}
	else
	{
		t = (BiTree)malloc(sizeof(CTNode));
		t->data = ch;
		t->lchild = create_tree(t->lchild);
		t->rchild = create_tree(t->rchild);
	}
	return t;
}
void Pretraverse_tree(BiTree P)
{
	int top = 0;
	CTNode *stack[N]; //又是因为直接写Bitree会出问题,写成这种原类型的形式比较好
	while (P || top != 0)
	{
		if (P != NULL)
		{
			printf("%c", P->data); //cat非空,打印cat
			stack[++top] = P; // 保存好cat 准备下一步深入底层
			P = P->lchild; //cat游标进入左孩子,上面的信息由当前数组栈的top下表所指向
		}
		else
		{
			P = stack[top--]->rchild;//你发现没有,top始终不会沉底,始终比cat高一层
		}
	}
	printf("先序遍历结束!\n");
}
void Midtraverse_tree(BiTree dog)
{
	char ch;
	scanf_s("%c", &ch, sizeof(ch));
	int top = 0;
	CTNode *stack[N];
	while (dog || top != 0)
	{
		if (dog != NULL)
		{
			stack[++top] = dog;
			dog = dog->lchild;
		}
		else
		{
			printf("%c", stack[top]->data);
			dog = stack[top--]->rchild;
		}
	}
	printf("中序遍历结束!\n");
}
void Postraverse_tree(BiTree puma)
{
	int top = -1;
	int flag[N];
	CTNode * stack[N];
	while (puma || top != -1)
	{
		if (puma != NULL)
		{
			stack[++top] = puma;
			flag[top] = 0;
			puma = puma->lchild;
		}
		else if (flag[top] == 0)//puma游标所指的节点虽然是空的,但是此节点左孩子已被访问
		{
			puma = stack[top]->rchild;
			flag[top] = 1;
		}
		else
		{
			printf("%c", stack[top--]->data);
		}
	}
	printf("后序遍历结束!\n");
}
void Leveltraverse_tree(BiTree eagle)
{
	BiTree queue[N];
	int rear = 0;
	int front = 0;
	queue[rear = (rear + 1) % N] = eagle;
	while (rear>front)//这里有一个数学原理:就是说这个函数使用的队列不可能造成循环,是竖直线性结构rear一定不会在front后面
	{
		printf("%c", queue[front = (front + 1) % N]->data);
		if (queue[front]->lchild != NULL)
		{
			queue[rear = (rear + 1) % N] = queue[front]->lchild;
		}
		if (queue[front]->rchild != NULL)
		{
			queue[rear = (rear + 1) % N] = queue[front]->rchild;
		}
	}
	printf("非封装形式层次遍历结束\n");
}
void Levelorder_sealed(BiTree dragon)
{
	CTNode val; //这里直接用BiTree val会报错,堆栈指针使用错误,用原类型然后取地址就可以
	QueueNode k;
	MatrixQueue S = init_q(&k); //这里也是,直接使用queue A=null 就会报错
	enqueue(S, dragon);
	while (!IsEmpty_q(S))
	{
		BiTree p = dequeue(S, &val);
		printf("%c", p->data);
		if (p->lchild != NULL)
		{
			enqueue(S, p->lchild);
		}
		if (p->rchild != NULL)
		{
			enqueue(S, p->rchild);
		}
	}
	printf("封装形式层次遍历结束!\n"); //2018年12月7日 15:06:31 搞定了,花了两天多时间!!!!!
}
void getwidth(BinTree girl)
{
	BinTree g = girl;
	BinTree queue[N];
	int front = 0;
	int rear = 0;
	int level = 0;
	int count_of_level = 0;
	queue[++rear] = g; count_of_level++;
	while (rear != front)
	{
		if (queue[rear]->nextsibling != NULL)
		{
			queue[++rear] = g->nextsibling;
			count_of_level++;
		}
		else
		{
			level++;
		}
	}
}
int getheight(BiTree m)
{
	BiTree queue[N];
	int front = 0, rear = 0, level = 0, last = 1;
	queue[++rear] = m;
	level++;
	while (front < rear)
	{
		front++;
		if (queue[front]->lchild)
		{
			queue[++rear] = queue[front]->lchild;
		}
		if (queue[front]->rchild)
		{
			queue[++rear] = queue[front]->rchild;
		}
		if (front==last)
		{
			last = rear;  //第一行为1个元素自动赋值,当第一行遍历完成之后第二行所有元素其实已经被rear记录过了,这个总的值
			level++;      //放在last里记录一下就可以了。两个都在动,第几个车站是上一辆车经过并且停留过的要记录一下
		}

	}
	return level;
}
int BT_depth1(BiTree T, int depth)
{
	int max1 = 0;//树高
	if (T)
	{
		if (T->lchild)
			BT_depth1(T->lchild, depth + 1);
		if (T->rchild)
			BT_depth1(T->rchild, depth + 1);
	}
	if (depth>max1)
		max1 = depth;
	return depth;
}
void GetLongestPath(BiTree T, char currentpath[], int &currentlength, char maxpath[], int &maxlength) //实时的长度放在currentlength里面存放
{
	if (T)
	{
		if (T->lchild == NULL && T->rchild == NULL) //只需要触底的时候比一下现在实时的长度即可,不用比较高度,否则就变成了层序遍历问题,会复杂化。
		{
			currentpath[currentlength] = T->data; 
			if (currentlength > maxlength)
			{
				for (int i = 0; i <=currentlength; i++) //currentpath[]用递归方法,实时跟踪每一条路径的数组, maxpath[]:最长路径存放的数组,会不断刷新
				{
					maxpath[i] = currentpath[i];
				}
				maxlength = currentlength;  //其实最长的长度+1就是树的高度,因为长度是由高度累加起来的,由边组成的。
			}
		}
		else
		{
			currentpath[currentlength++] = T->data; //如果没有触底,那么很简单,直接入队,放在数组里存着,放在一个纯线性结构里面可以保存一路上遇到的所有节点的值。
			GetLongestPath(T->lchild,currentpath,currentlength,maxpath,maxlength);//进入递归层之后是可以带着上一层的数值进行计算的,这一层要花不少时间,左孩子访问完了之后一直返回到第一层
			GetLongestPath(T->rchild, currentpath, currentlength, maxpath, maxlength);//每次递归访问玩之后多加了一个节点???要减掉?????
			currentlength--; 
		}
	}
}
int Height(BiTree T)
{
	if (T == NULL) return 0;
	else
	{
		int m = Height(T->lchild); //递归求高度
		int n = Height(T->rchild);
		return (m > n) ? (m + 1) : (n + 1);
	}
}
//Graph
void CreateAdjListGraph(AGraph G)
{
	ArcNode *e;//将用边之属性将内存分配之
	printf("please input the number of the Vertex:");
	scanf_s("%d", &G->vexnum);
	getchar();/*吃掉回车*/
	printf("please input the number of the Arc:");
	scanf_s("%d", &G->arcnum);
	getchar();/*吃掉回车*/
	for (int i = 0; i < G->vexnum;i++) //创建G.vexnum个定点
	{
		printf("input the node data(char):");
		scanf_s("%c",&G->adjlist[i].data,sizeof(VertexType));
		getchar();/*吃掉回车*/
		G->adjlist[i].firstarc = NULL;
	}
	for (int m = 0; m < G->arcnum; m++) //创建G.arcnum个边
	{
		int k, j, w; //通过相邻两个节点的下标和他们之中的边的权重来创建一个无向图
		printf("请输入相邻两个节点以及他们之间无向权重(三个整数):");
		scanf_s("%d %d %d",&k,&j,&w);
		e = (ArcNode *)malloc(sizeof(ArcNode));
		e->adjvex = j; //边对应的点的下标
		e->weigth = w; //边的权重
		e->nextarc = G->adjlist[j].firstarc; //边的下一条边的地址是点表中首节点的地址
		G->adjlist[k].firstarc = e;//分配一块内存给e,把e这个实际的节点挂到adjlist数组相应元素的指针域中
		// 另一个节点要和上一个连上去
		e = (ArcNode *)malloc(sizeof(ArcNode));
		e->adjvex = k;
		e->weigth = w;
		e->nextarc = G->adjlist[k].firstarc;//通过边表节点建立两个相连的节点之间的关系
		G->adjlist[j].firstarc = e;
	}
}
void PrintAdjListGraph(AGraph G)
{
	for (int i = 0; i < G->vexnum; i++) //遍历总次数=顶点数
	{
		ArcNode *p = G->adjlist[i].firstarc;
		printf("Vertex节点内部数据域的值是:%c\n",G->adjlist[i].data);
		while (p)
		{
			printf("第%d号顶点的权重值是:",p->adjvex);
			printf("%d",p->weigth);
			p = p->nextarc;
		}	
		printf("\n");
	}
	printf("\n");
}
void BFS(AGraph G, int v) //
{
//	ArcNode *p;
//	MatrixQueue Q;
//	init_q(Q);
//	printf("%c",G->adjlist[p->adjvex].data);
//	visited[v] = true;
//	//enqueue(Q,v);
//	while (!IsEmpty_q(Q))
//	{
//		//dequeue(Q,v);
//		p = G->adjlist[v].firstarc;
//		while (p)
//		{
//			if (!visited[p->adjvex])
//			printf("%c", G->adjlist[p->adjvex].data);
//			visited[p->adjvex] = true;
//			enqueue(Q, p->adjvex);
//		}
//		p = p->nextarc;
//	}
//
}
void DFS(AGraph G, int v)
{
//	ArcNode *p;
//	printf("%c", G->adjlist[p->adjvex].data);
//	visited[v] = true;
//	p = G->adjlist[v].firstarc;
//	while (p)
//	{
//		if (!visited[v])
//		{
//			DFS(G,p->adjvex);
//		}
//		p = p->nextarc;
//	}
}
//Search and Sort
void SelectSort(LinkList head)
{
	LinkList p, q, r, tmp, S[N];
	p = head->next; q = p; r = head;
	int i =0, min = 0, minvalue = p->data;
	while (q->next)
	{		
		while (p)
		{	
			S[i] = p;//每次重头到尾一次遍历,找到目前最小的值,把其节点的地址放入S【min】中保存
			if (S[i]->data < minvalue)
			{    
				minvalue = S[i]->data;//通过数组下标可以找到最小值对应节点在链表的位置
				min = i;   //printf(" \n running... %d %d ", min, S[i]->data);	
			}
			i++;
			p = p->next;	 //printf(" \n GTX460 %d %d %d", i, min, S[min]->data);	
		}	//printf("S[%d]=%d \n", min,S[min]->data); 	
		if (min == 0)
		{
			printf("jump!\n");	 //如果最小值就存在于最前面的节点,那么是不用调整的,只需要将所有指针瞬移一格,然后把i和min重置为0,最新的最小值更新为这个节点下面一格节点的值即可			
		}
		else if(q->next==S[min]) // 如果这个节点的值不是最小的,但是和最小节点相邻,那么只需要将这两个相邻节点指针互换位置即可
		{
			q->next = S[min]->next;
			S[min]->next = q;
			r->next = S[min];	
		}
		else           // 如果这个节点的值不是最小的,也不和最小的节点相邻,那么调整他们整体的位置(至少三个节点以上的调整)
		{
			tmp = q->next;
			q->next = S[min]->next; //这里有可能是空值赋给了q的指针域
			S[min - 1]->next = q;  //printf("hello\n"); exit(-1);
			S[min]->next = tmp;
			r->next = S[min];		
		}
		r = r->next; q = r->next; p = q;		
		i = min = 0; minvalue = p->data;   //printf("current minnum is :%d\n", r->data); printf("next head is :%d\n", p->data); //exit(-1);		
	}
}
void selectsort(LinkList head)
{
	int tmp;
	LinkList p = head->next, q =NULL;
	for (p; p; p = p->next)
	{
		q = p->next;
		for (q; q; q = q->next)
		{
			if (p->data > q->data)
			{
				tmp = q->data;
				q->data = p->data;
				p->data = tmp;
			}
		}	
	}
}
void HeapSort(LinkList)
{

}
void ShellSort(LinkList)
{

}
bool TopologicalSort(AGraph G)
{
	MatrixQueue a=NULL;
	init_q(a);
	for (int i = 0; i < G->vexnum; i++)
	{

	}
	return true;
}

the code above is based on the compiler microsoft VisioStudio 2015

i will show the Mac Xcode version code here:

//
//  main.cpp
//  X21
//
//  Created by novigard on 3/2/19.
//  Copyright © 2019 novigard. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define  MaxSize 100
#define  N 20
typedef  char VertexType;
typedef  int EdgeType;
typedef struct LNODE
{
    int data;
    struct LNODE * next;
}LNODE, *LinkList;                    // definition of the LinkList
typedef struct StackNode
{
    int data;
    int top;
    int bottom;
}StackNode, *Stack;                // definition of the Stack
typedef struct CTNode
{
    int data;
    struct CTNode *lchild;
    struct CTNode *rchild;
}CTNode, *BiTree;                    // definition of the CT tree
typedef struct CSNode
{
    char data;
    struct CSNode* firstchild;
    struct CSNode* nextsibling;
}CSNode, *BinTree;                    // definition of the CS tree
typedef struct QueueNode
{
    BiTree *queue;   //一个将来用作数组名的指针变量queue
    int front;
    int rear;
}QueueNode, *MatrixQueue;       // definition of the queue
typedef struct MGraph
{
    int vexnum, arcnum;//当前定点数和弧的数量
    VertexType Vex[N]; //存定点第一个数组
    EdgeType Edge[N][N]; //存边第一个数组
}MGraph;                           // Matrix Graph
typedef struct ArcNode
{
    int adjvex;  //边对应节点的下标
    int weigth;  //用于存储权值
    struct ArcNode * nextarc;  //链域,指向下一个邻接点 (边向顶点方向移动)
}ArcNode;                         //边表节点
typedef struct VNode
{
    VertexType data;   //存储顶点数据的信息
    ArcNode *firstarc;  //定点表对应边表的头指针  (顶点向边方向移动)
}VNode,AdjList[N];                  //顶点表节点
typedef struct ALGraph
{
    AdjList adjlist;
    int vexnum;
    int arcnum;
}ALGraph ,*AGraph;                //宏观定义邻接表的大节点类型
typedef struct
{
    VertexType vex[N];
    EdgeType edge[N][N];
    int vexnum, arcnum;
}MarixGraph;

LinkList createlist();
bool traverse_list(LinkList);
int length_of_the_list(LinkList);
void insert_elem(LinkList, int);
void Bubble_sort_list(LinkList);
void dele_elem(LinkList);
MatrixQueue init_q(MatrixQueue);
bool IsEmpty_q(MatrixQueue);
bool IsFull_q(MatrixQueue);
void enqueue(MatrixQueue, BiTree);
BiTree dequeue(MatrixQueue, BiTree);
void traverse_q(MatrixQueue);
BiTree create_tree(BiTree);
void Pretraverse_tree(BiTree);
void Midtraverse_tree(BiTree);
void Postraverse_tree(BiTree);
void Leveltraverse_tree(BiTree);
void Levelorder_sealed(BiTree);
int getheight(BiTree);
int BT_depth1(BiTree,int);
int Height(BiTree);
void CreateAdjListGraph(AGraph);
void PrintAdjListGraph(AGraph);
bool visited[MaxSize];
void BFS(AGraph,int);
void DFS(AGraph, int);
void SelectSort(LinkList);
void selectsort(LinkList);
void HeapSort(LinkList);
void ShellSort(LinkList);
void GetLongestPath(BiTree T, char currentpath[], int &currentlength, char maxpath[], int &maxlength);
//main function content
int main()
{

    CTNode M;
    printf("hello russul\n");
    BiTree B = create_tree(&M); //这里有时候用直接空值变量会好点,有时候用取地址不报错
    Leveltraverse_tree(B);
    //char currentpath[N], maxpath[N];
    //int currentlength = 0, maxlength = 0;
    //GetLongestPath(n, currentpath, currentlength, maxpath, maxlength);
    /*for (int i = 0; i <= maxlength; i++)
    {
        printf("%c ",maxpath[i]);
    }*/
}
//Linklist
LinkList createlist()
{
    LinkList L, T;
    int len, tmp;
    printf("请输入链表的长度:\n");
    scanf("%d", &len);
    L = (LinkList)malloc(sizeof(LNODE));//作为一个头动态游标;指针不停地动,指向需要的地方。
    T = L; //作为一个尾动态游标(尾指针T),精髓就在于这个尾巴是一个虚拟的尾巴,不是加在头结点后面的实体节点。
    T->next = NULL;
    for (int i = 1; i <= len; i++)
    {
        printf("请输入第%d个元素的值:\n", i);
        scanf("%d", &tmp);
        LinkList pBody = (LinkList)malloc(sizeof(LNODE));
        pBody->data = tmp;
        pBody->next = NULL;
        /* **********************************************************************************************************/
        T->next = pBody;// T->next:T访问它指向的当前节点的指针域的内容,指针域内容指向第二个节点。
        T = pBody;//新生成的节点当做现在的尾节点(新节点的地址发送到尾指针T中,这样T就可以继续指向新节点了)
        
        /* **********************************************************************************************************/
    }  //尾游标增加过一个节点之后当然需要移动位置,从而继续增加第二个节点,移动位置就是新节点的地址赋值给尾游标。
    return L;
}   //《尾插法实现单链表的创建》 2018.7.24
int length_of_the_list(LinkList K)
{
    int length = 0;
    LinkList cat = K->next;
    while (cat->next != NULL)//利用尾指针指向的那个元素的指针域为null来判断是否游到表尾
    {
        length++;
        cat = cat->next;//单链表顺序遍历的核心思想,从一个未知的虚拟地址空间cat开始,cat指向的那个不虚拟的实体里存放的下一个实体的地址
    }
    return length + 1;
}
void insert_elem(LinkList tiger, int m)
{
    int i = 0;
    LinkList snake = tiger->next; //遍历的时候要分情况
    LinkList pBody = (LinkList)malloc(sizeof(LNODE));
    pBody->data = 500;
    for (i; i < m - 1; ++i)
    {
        snake = snake->next;
    }
    pBody->next = snake->next;
    snake->next = pBody;
}
void dele_elem(LinkList lion)
{
    int n;
    LinkList fish = lion->next;
    printf("x后面的元素将被删除,请输入x:");
    scanf("%d", &n);
    for (int i = 0; i < n - 1; ++i)//假设要删除第一个元素后面的元素,那么一次都不需要循环,游标默认停留在第一个元素那,指向第一个元素。
    {
        fish = fish->next;
    }
    fish->next = fish->next->next;//单次覆盖即可达到目的。    把第三个节点的地址存放到第一个节点指针域中去就行了
    
}
void Bubble_sort_list(LinkList panda)
{
    int i, j;
    int k = length_of_the_list(panda);
    LinkList bear = panda->next;
    LinkList bear1 = bear;
    LinkList eagle=(LNODE *)malloc(sizeof(LNODE));
    printf("冒泡排序过后的元素依次为:\n");
    for (i = 0; i < k; i++)
    {
        for (j = 0; j < k - 1; j++)
        {
            if (bear->data > bear->next->data)
            {
                eagle->data = bear->data;
                bear->data = bear->next->data;
                bear->next->data = eagle->data;
            }
            bear = bear->next;
        }
        bear = bear1;//从头开始计算,要不然bear游到了末尾就没法回头了
    }
    
}
bool traverse_list(LinkList head)
{
    LinkList p = head->next;
    while (p)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    return true;
}
//Queue
MatrixQueue init_q(MatrixQueue m) //数组初始化
{
    m->queue = (BiTree *)malloc(sizeof(CTNode)*MaxSize);
    m->front = 0;
    m->rear = 0;
    return m;
}
bool IsFull_q(MatrixQueue s)
{
    if ((s->rear + 1) % MaxSize == s->front)
        return true;
    else
        return false;
}
bool IsEmpty_q(MatrixQueue m)
{
    if (m->rear == m->front)
        return true;
    else
        return false;
}
void enqueue(MatrixQueue c, BiTree val)
{
    if (!IsFull_q(c))
    {
        c->queue[c->rear] = val;
        c->rear = (c->rear + 1) % MaxSize;
    }
    else
        printf("enqueue failure! \n");
}
BiTree dequeue(MatrixQueue d, BiTree val)
{
    if (!IsEmpty_q(d))
    {
        val = d->queue[d->front];
        d->front = (d->front + 1) % MaxSize;
        return val;
    }
    else
    {
        printf("queue is full \n");
    }
    return 0;
}
void traverse_q(MatrixQueue k)
{
    int i = k->front;
    while (i != k->rear)
    {
        printf("%d\n", k->queue[i]);
        i = (i + 1) % MaxSize;
    }
}
//CT Binary Tree
BiTree create_tree(BiTree t)
{
    char ch;
    scanf("%c",&ch);
    if (ch == ' ')
    {
        t = NULL;
    }
    else
    {
        t = (BiTree)malloc(sizeof(CTNode));
        t->data = ch;
        t->lchild = create_tree(t->lchild);
        t->rchild = create_tree(t->rchild);
    }
    return t;
}
void Pretraverse_tree(BiTree P)
{
    int top = 0;
    CTNode *stack[N]; //又是因为直接写Bitree会出问题,写成这种原类型的形式比较好
    while (P || top != 0)
    {
        if (P != NULL)
        {
            printf("%c", P->data); //cat非空,打印cat
            stack[++top] = P; // 保存好cat 准备下一步深入底层
            P = P->lchild; //cat游标进入左孩子,上面的信息由当前数组栈的top下表所指向
        }
        else
        {
            P = stack[top--]->rchild;//你发现没有,top始终不会沉底,始终比cat高一层
        }
    }
    printf("先序遍历结束!\n");
}
void Midtraverse_tree(BiTree dog)
{
    char ch;
    scanf("%c", &ch);
    int top = 0;
    CTNode *stack[N];
    while (dog || top != 0)
    {
        if (dog != NULL)
        {
            stack[++top] = dog;
            dog = dog->lchild;
        }
        else
        {
            printf("%c", stack[top]->data);
            dog = stack[top--]->rchild;
        }
    }
    printf("中序遍历结束!\n");
}
void Postraverse_tree(BiTree puma)
{
    int top = -1;
    int flag[N];
    CTNode * stack[N];
    while (puma || top != -1)
    {
        if (puma != NULL)
        {
            stack[++top] = puma;
            flag[top] = 0;
            puma = puma->lchild;
        }
        else if (flag[top] == 0)//puma游标所指的节点虽然是空的,但是此节点左孩子已被访问
        {
            puma = stack[top]->rchild;
            flag[top] = 1;
        }
        else
        {
            printf("%c", stack[top--]->data);
        }
    }
    printf("后序遍历结束!\n");
}
void Leveltraverse_tree(BiTree eagle)
{
    BiTree queue[N];
    int rear = 0;
    int front = 0;
    queue[rear = (rear + 1) % N] = eagle;
    while (rear>front)//这里有一个数学原理:就是说这个函数使用的队列不可能造成循环,是竖直线性结构rear一定不会在front后面
    {
        printf("%c", queue[front = (front + 1) % N]->data);
        if (queue[front]->lchild != NULL)
        {
            queue[rear = (rear + 1) % N] = queue[front]->lchild;
        }
        if (queue[front]->rchild != NULL)
        {
            queue[rear = (rear + 1) % N] = queue[front]->rchild;
        }
    }
    printf("非封装形式层次遍历结束\n");
}
void Levelorder_sealed(BiTree dragon)
{
    CTNode val; //这里直接用BiTree val会报错,堆栈指针使用错误,用原类型然后取地址就可以
    QueueNode k;
    MatrixQueue S = init_q(&k); //这里也是,直接使用queue A=null 就会报错
    enqueue(S, dragon);
    while (!IsEmpty_q(S))
    {
        BiTree p = dequeue(S, &val);
        printf("%c", p->data);
        if (p->lchild != NULL)
        {
            enqueue(S, p->lchild);
        }
        if (p->rchild != NULL)
        {
            enqueue(S, p->rchild);
        }
    }
    printf("封装形式层次遍历结束!\n"); //2018年12月7日 15:06:31 搞定了,花了两天多时间!!!!!
}
void getwidth(BinTree girl)
{
    BinTree g = girl;
    BinTree queue[N];
    int front = 0;
    int rear = 0;
    int level = 0;
    int count_of_level = 0;
    queue[++rear] = g; count_of_level++;
    while (rear != front)
    {
        if (queue[rear]->nextsibling != NULL)
        {
            queue[++rear] = g->nextsibling;
            count_of_level++;
        }
        else
        {
            level++;
        }
    }
}
int getheight(BiTree m)
{
    BiTree queue[N];
    int front = 0, rear = 0, level = 0, last = 1;
    queue[++rear] = m;
    level++;
    while (front < rear)
    {
        front++;
        if (queue[front]->lchild)
        {
            queue[++rear] = queue[front]->lchild;
        }
        if (queue[front]->rchild)
        {
            queue[++rear] = queue[front]->rchild;
        }
        if (front==last)
        {
            last = rear;  //第一行为1个元素自动赋值,当第一行遍历完成之后第二行所有元素其实已经被rear记录过了,这个总的值
            level++;      //放在last里记录一下就可以了。两个都在动,第几个车站是上一辆车经过并且停留过的要记录一下
        }
        
    }
    return level;
}
int BT_depth1(BiTree T, int depth)
{
    int max1 = 0;//树高
    if (T)
    {
        if (T->lchild)
            BT_depth1(T->lchild, depth + 1);
        if (T->rchild)
            BT_depth1(T->rchild, depth + 1);
    }
    if (depth>max1)
        max1 = depth;
    return depth;
}
void GetLongestPath(BiTree T, char currentpath[], int &currentlength, char maxpath[], int &maxlength) //实时的长度放在currentlength里面存放
{
    if (T)
    {
        if (T->lchild == NULL && T->rchild == NULL) //只需要触底的时候比一下现在实时的长度即可,不用比较高度,否则就变成了层序遍历问题,会复杂化。
        {
            currentpath[currentlength] = T->data;
            if (currentlength > maxlength)
            {
                for (int i = 0; i <=currentlength; i++) //currentpath[]用递归方法,实时跟踪每一条路径的数组, maxpath[]:最长路径存放的数组,会不断刷新
                {
                    maxpath[i] = currentpath[i];
                }
                maxlength = currentlength;  //其实最长的长度+1就是树的高度,因为长度是由高度累加起来的,由边组成的。
            }
        }
        else
        {
            currentpath[currentlength++] = T->data; //如果没有触底,那么很简单,直接入队,放在数组里存着,放在一个纯线性结构里面可以保存一路上遇到的所有节点的值。
            GetLongestPath(T->lchild,currentpath,currentlength,maxpath,maxlength);//进入递归层之后是可以带着上一层的数值进行计算的,这一层要花不少时间,左孩子访问完了之后一直返回到第一层
            GetLongestPath(T->rchild, currentpath, currentlength, maxpath, maxlength);//每次递归访问玩之后多加了一个节点???要减掉?????
            currentlength--;
        }
    }
}
int Height(BiTree T)
{
    if (T == NULL) return 0;
    else
    {
        int m = Height(T->lchild); //递归求高度
        int n = Height(T->rchild);
        return (m > n) ? (m + 1) : (n + 1);
    }
}
//Graph
void CreateAdjListGraph(AGraph G)
{
    ArcNode *e;//将用边之属性将内存分配之
    printf("please input the number of the Vertex:");
    scanf("%d", &G->vexnum);
    getchar();/*吃掉回车*/
    printf("please input the number of the Arc:");
    scanf("%d", &G->arcnum);
    getchar();/*吃掉回车*/
    for (int i = 0; i < G->vexnum;i++) //创建G.vexnum个定点
    {
        printf("input the node data(char):");
        scanf("%c",&G->adjlist[i].data);
        getchar();/*吃掉回车*/
        G->adjlist[i].firstarc = NULL;
    }
    for (int m = 0; m < G->arcnum; m++) //创建G.arcnum个边
    {
        int k, j, w; //通过相邻两个节点的下标和他们之中的边的权重来创建一个无向图
        printf("请输入相邻两个节点以及他们之间无向权重(三个整数):");
        scanf("%d %d %d",&k,&j,&w);
        e = (ArcNode *)malloc(sizeof(ArcNode));
        e->adjvex = j; //边对应的点的下标
        e->weigth = w; //边的权重
        e->nextarc = G->adjlist[j].firstarc; //边的下一条边的地址是点表中首节点的地址
        G->adjlist[k].firstarc = e;//分配一块内存给e,把e这个实际的节点挂到adjlist数组相应元素的指针域中
        // 另一个节点要和上一个连上去
        e = (ArcNode *)malloc(sizeof(ArcNode));
        e->adjvex = k;
        e->weigth = w;
        e->nextarc = G->adjlist[k].firstarc;//通过边表节点建立两个相连的节点之间的关系
        G->adjlist[j].firstarc = e;
    }
}
void PrintAdjListGraph(AGraph G)
{
    for (int i = 0; i < G->vexnum; i++) //遍历总次数=顶点数
    {
        ArcNode *p = G->adjlist[i].firstarc;
        printf("Vertex节点内部数据域的值是:%c\n",G->adjlist[i].data);
        while (p)
        {
            printf("第%d号顶点的权重值是:",p->adjvex);
            printf("%d",p->weigth);
            p = p->nextarc;
        }
        printf("\n");
    }
    printf("\n");
}
void BFS(AGraph G, int v) //
{
    //    ArcNode *p;
    //    MatrixQueue Q;
    //    init_q(Q);
    //    printf("%c",G->adjlist[p->adjvex].data);
    //    visited[v] = true;
    //    //enqueue(Q,v);
    //    while (!IsEmpty_q(Q))
    //    {
    //        //dequeue(Q,v);
    //        p = G->adjlist[v].firstarc;
    //        while (p)
    //        {
    //            if (!visited[p->adjvex])
    //            printf("%c", G->adjlist[p->adjvex].data);
    //            visited[p->adjvex] = true;
    //            enqueue(Q, p->adjvex);
    //        }
    //        p = p->nextarc;
    //    }
    //
}
void DFS(AGraph G, int v)
{
    //    ArcNode *p;
    //    printf("%c", G->adjlist[p->adjvex].data);
    //    visited[v] = true;
    //    p = G->adjlist[v].firstarc;
    //    while (p)
    //    {
    //        if (!visited[v])
    //        {
    //            DFS(G,p->adjvex);
    //        }
    //        p = p->nextarc;
    //    }
}
//Search and Sort
void SelectSort(LinkList head)
{
    LinkList p, q, r, tmp, S[N];
    p = head->next; q = p; r = head;
    int i =0, min = 0, minvalue = p->data;
    while (q->next)
    {
        while (p)
        {
            S[i] = p;//每次重头到尾一次遍历,找到目前最小的值,把其节点的地址放入S【min】中保存
            if (S[i]->data < minvalue)
            {
                minvalue = S[i]->data;//通过数组下标可以找到最小值对应节点在链表的位置
                min = i;   //printf(" \n running... %d %d ", min, S[i]->data);
            }
            i++;
            p = p->next;     //printf(" \n GTX460 %d %d %d", i, min, S[min]->data);
        }    //printf("S[%d]=%d \n", min,S[min]->data);
        if (min == 0)
        {
            printf("jump!\n");     //如果最小值就存在于最前面的节点,那么是不用调整的,只需要将所有指针瞬移一格,然后把i和min重置为0,最新的最小值更新为这个节点下面一格节点的值即可
        }
        else if(q->next==S[min]) // 如果这个节点的值不是最小的,但是和最小节点相邻,那么只需要将这两个相邻节点指针互换位置即可
        {
            q->next = S[min]->next;
            S[min]->next = q;
            r->next = S[min];
        }
        else           // 如果这个节点的值不是最小的,也不和最小的节点相邻,那么调整他们整体的位置(至少三个节点以上的调整)
        {
            tmp = q->next;
            q->next = S[min]->next; //这里有可能是空值赋给了q的指针域
            S[min - 1]->next = q;  //printf("hello\n"); exit(-1);
            S[min]->next = tmp;
            r->next = S[min];
        }
        r = r->next; q = r->next; p = q;
        i = min = 0; minvalue = p->data;   //printf("current minnum is :%d\n", r->data); printf("next head is :%d\n", p->data); //exit(-1);
    }
}
void selectsort(LinkList head)
{
    int tmp;
    LinkList p = head->next, q =NULL;
    for (p; p; p = p->next)
    {
        q = p->next;
        for (q; q; q = q->next)
        {
            if (p->data > q->data)
            {
                tmp = q->data;
                q->data = p->data;
                p->data = tmp;
            }
        }
    }
}
void HeapSort(LinkList)
{
    
}
void ShellSort(LinkList)
{
    
}
bool TopologicalSort(AGraph G)
{
    MatrixQueue a=NULL;
    init_q(a);
    for (int i = 0; i < G->vexnum; i++)
    {
        
    }
    return true;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值