数据结构 の 实验(Update : 22.11.15)

文章目录

  • 顺序表
  • 链表
  • 顺序表
  • 链表
  • 顺序栈:进制转换(16进制内)
  • 循环队列:舞伴配对问题
  • 顺序栈:表达式求值
  • 二叉树
  • 查找
  • 排序算法

顺序表

数据结构 の 实验(Update : 22.11.15)_第1张图片

#include
using namespace std;

//动态顺序表
#define Listsize 100

typedef struct node{
	int* base; //基地址
	int len;   //表长
	int size;  //容量
}Sqlist;


//sequence list 按顺序排列的表
//初始化
void InitSqlist(Sqlist &L){
	L.base = (int *)malloc( Listsize * sizeof(int) );
	if(!L.base){
		puts("初始化失败!");
		return ;
	}
	L.len = 0;
	L.size = 100;
}

/*
个人理解:
线性表就类似于数组

初始化就类似于创建一个数组 , 分配一个首地址 ,然后分配内存就是初始化数组大小 用 malloc
线性表的用法和数字一样 , 也是用数组名(首地址名) + 下标 的方法来引用
如果数组不够大 就用 realloc 为 数组重新分配内存

*/


//尾插
void TailInsert(Sqlist &L ,int key){
	
	if(L.len == L.size){
		int* newbase = (int *)realloc(L.base , (L.size + Listsize) * sizeof(int) );
		if(!newbase){
			puts("扩容失败!");
			return ;
		}
		
		L.base = newbase;
		L.size += Listsize;
						
	}
	
	L.base[++L.len] = key;
}

//debug
void out(Sqlist &L){
	for(int i=1;i<=L.len;i++){
		cout << L.base[i] << " ";
	}
	cout << "\n" ;
}

void solve1(Sqlist LA){
	
	Sqlist LB , LC;
	
	InitSqlist(LB);
	InitSqlist(LC);
	
	for(int i=1;i<=LA.len;i++){
		int date = LA.base[i];
		
		if(date > 0){
			TailInsert(LB , date);
		}else{
			TailInsert(LC , date);
		}
	}
	
	//	out(LB); out(LC);
	
}

/*
思路:不消耗空间 , 先冒泡排序( O(n*n) ) ,然后 LB 的首地址放负数数首地址 , LC 的首地址放正数首地址,修改长度即可
*/

void solve2(Sqlist &LA){
	
	Sqlist LB , LC;
	
	int n = LA.len , cnt = 0;
	
	//非降序起泡排序
	for(int i = 1;i < n; i++){
		for(int j = 1; j < n - i ; j++){
			if(LA.base[j] > LA.base[j+1]){
				swap(LA.base[j] , LA.base[j+1]);
			}
		}
	}
	
	out(LA);

	for(int i=1;i<=n;i++){
		if(LA.base[i] < 0){
			cnt++;
		}else{
			break;
		}
	}
	//LB 负的 LC 正的
	
//	cout << cnt << "\n" ;
	
	LB.base = LA.base;
	LB.len = cnt;
	
	LC.base = &LA.base[cnt];
	LC.len = LA.len - cnt;
	
//	out(LB);
//	out(LC);
	
}

int main(){
	
	Sqlist LA;
	int n;
	
	cin >> n;
	InitSqlist(LA);	
	
	for(int i=1;i<=n;i++){
		int num;
		cin >> num;
		TailInsert(LA , num);
	}
	
//	out(LA);

	solve1(LA);
	
	solve2(LA);
	
	return 0;
}

/*
10
1 -2 3 -7 21 33 -1 56 -12 11
*/

链表

数据结构 の 实验(Update : 22.11.15)_第2张图片

#include
using namespace std;

struct node{
	int date;
	struct node* next;
};

typedef struct node* List;

void Init(List &L){
	L = (List) malloc(sizeof(List));
	L -> next = NULL;
}

// L 放的是当前位置的地址 , L -> next 放的是下一个位置的地址

void Tailinsert(List &L,int date){
	List newnode = (List) malloc (sizeof(List));
	
	newnode -> date = date;
	newnode -> next = NULL;
	
	List L1 = L;
	while(L1 -> next != NULL) L1 = L1 -> next;
	
	L1 -> next = newnode;	
}

void out(List LA){
	
	List L = LA -> next;
	
	while(L != NULL){
		cout << L -> date << " ";
		L = L -> next;
	}
		
	puts("");
}

void copy(List LA ,List &LB){
	
	List L = LA -> next;
	
	while(L != NULL){
		
		int date = L -> date;
		
		Tailinsert(LB , date);
		
		L = L -> next;
	}
	
	
}

int main(){
	
	List LA;
	List LB;
	List LC;
	
	Init(LA);
	Init(LB);
	Init(LC);
	
	int n , num;
	
	cin >> n;
	
	for(int i=1;i<=n;i++){
		cin >> num;
		Tailinsert(LA , num);
	}
	
	out(LA);
	
	copy(LA , LB);

	out(LB);
	
	copy(LB , LC);
	
	out(LC);


	
}
/*
5
4 2 1 3 -3
*/

顺序表

① 随机产生一组两位数整数,建立线性表的顺序存储结构。

② 实现该线性表的遍历。

③ 在该顺序表中查找某一元素,查找成功显示查找元素,否则显示查找失败。

④ 在该顺序表中删除或插入指定元素。

#include
using namespace std;
#define Listsize 100

typedef struct node{
	int* base; //基地址
	int len;   //表长
	int size;  //容量
}Sqlist;

void InitSqlist(Sqlist &L){
	L.base = (int *)malloc( Listsize * sizeof(int) );
	if(!L.base){
		puts("初始化失败!");
		return ;
	}
	L.len = 0;
	L.size = 100;
}

//尾插函数
void TailInsert(Sqlist &L ,int key){
	
	//扩容 , 每次给 100 个内存空间
	if(L.len == L.size){
		int* newbase = (int *)realloc(L.base , (L.size + Listsize) * sizeof(int) );
		if(!newbase){
			puts("扩容失败!");
			return ;
		}
		
		L.base = newbase;
		L.size += Listsize;
						
	}
	
	L.base[++L.len] = key;
}

void out(Sqlist &L){
	for(int i=1;i<=L.len;i++){
		cout << L.base[i] << " ";
	}
	cout << "\n" ;
}

//随机产生 15个 2 位正整数
void go(Sqlist &L){
	for(int i=1;i<=15;i++){
		int key = rand() % 90 + 10;
		TailInsert(L , key);
	}
}


void find(Sqlist &L , int key){
	for(int i=1;i<=L.len;i++){
		if(L.base[i] == key){
			cout << "查找成功\n";
			return ;
		}
	}
	cout << "查找失败\n" ;
	return ;
}

void IdInsert(Sqlist &L ,int key,int id){
	
	if(L.len == L.size){
		int* newbase = (int *)realloc(L.base , (L.size + Listsize) * sizeof(int) );
		if(!newbase){
			puts("扩容失败!");
			return ;
		}
		
		L.base = newbase;
		L.size += Listsize;
						
	}
	for(int i=L.len+1;i>id;i--){
		L.base[i] = L.base[i-1];
	}
	L.base[id] = key;
	L.len++;
		
}

void Del(Sqlist &L,int key){
	
	int num = 0;
	
	for(int i=1;i<=L.len;i++){
		if(L.base[i] == key) num++;
	}
	
	while(num--){
		for(int i=1;i<=L.len;i++){
			if(L.base[i] == key){
				for(int j=i+1;j<=L.len;j++){
					L.base[j-1] = L.base[j];
				}
				L.len--;
				break;
			}
		}
	}
	
}


int main(){
	
	srand(unsigned(time(0)));
	Sqlist l1;
	
	//初始化 线性表
	InitSqlist(l1);
	
	// 1 . 产生数据 , 建立线性表
	go(l1);
	
	// 2 . 实现遍历
	out(l1);
	
	// 3 . 实现查找
	
	int kk = 0;
	
	cout << "请输入要查找的元素:\n" ;
	
	cin >> kk;
	
	find(l1,kk);
	
	// 4 .实现元素的删除
	
	cout << "请输入要删除的元素:\n" ;
	
	int ks = 0;
	
	cin >> ks;
	
	Del(l1,ks);
	
	out(l1);
	
	// 5 .实现元素的插入
	
	cout << "请输入要插入的元素 和 其位序:\n" ;
	
	int key , id;
	
	cin >> key >> id;
	
	IdInsert(l1,key,id);
	
	out(l1);
	
		 
	
	return 0;
}


链表

① 输入一组整型元素序列,使用尾插法建立一个带有头结点的单链表。

② 实现该线性表的遍历。

③ 实现单链表的就地逆置。

④ 建立两个按值递增有序的单链表,将他们合并成一个按值递减有序的单链表。要求利用原来的存储空间,并且新表中没有相同的元素。

#include
using namespace std;

struct node{
	int date;
	struct node* next;
};

typedef struct node* List;

void Init(List &L){
	L = (List) malloc(sizeof(List));
	L -> next = NULL;
}

// L 放的是当前位置的地址 , L -> next 放的是下一个位置的地址

void Tailinsert(List &L,int date){
	List newnode = (List) malloc (sizeof(List));
	
	newnode -> date = date;
	newnode -> next = NULL;
	
	List L1 = L;
	while(L1 -> next != NULL) L1 = L1 -> next;
	
	L1 -> next = newnode;	
}

void Headinsert(List &L,int date){
	List newnode = (List) malloc (sizeof(List));
	
	List L1 = L;
	
	newnode -> date = date;
	newnode -> next = L1 -> next;
	L1 -> next = newnode;	
}

void out(List LA){
	
	List L = LA -> next;
	
	while(L != NULL){
		cout << L -> date << " ";
		L = L -> next;
	}
		
	puts("");
}

void Lunionn(List l1 , List l2 , List &ls){
	
	l1 = l1 -> next;
	l2 = l2 -> next; 
	//跳过头节点
	
	List head = ls;//头指针
	
	while(l1 && l2){
		int date1 = l1 -> date;
		int date2 = l2 -> date;
		
		List tmp1 = l1 -> next;
		List tmp2 = l2 -> next;
		
		if(date1 == date2){
			
			l1 -> next = head -> next;
			head -> next = l1;
			 
			l1 = tmp1;
			l2 = tmp2;
		}else if(date1 < date2){
			l1 -> next = head -> next;
			head -> next = l1;
			 
			l1 = tmp1;
		}else{
			l2 -> next = head -> next;
			head -> next = l2;
			 
			l2 = tmp2;
		}
	}
	
	while(l1){
		
		List tmp1 = l1 -> next;

		l1 -> next = head -> next;
		head -> next = l1;
		 
		l1 = tmp1;
	}
	
	while(l2){
		List tmp2 = l2 -> next;
		
		l2 -> next = head -> next;
		head -> next = l2;
		 
		l2 = tmp2;
	}
	
}


int main(){
	
	List l1;
	List l2;
	int n , key , m;
	
	Init(l1);
	Init(l2);
	
	cout << "输入元素 , 尾插建立单链表\n" ;
	//1. 输入元素 , 尾插建立单链表
	
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> key;
		Tailinsert(l1,key);
	}
	
	
	// 2. 实现链表的遍历
	out(l1);
	
	cout << "链表的就地逆置(头插法)\n" ;
	// 3.链表的就地逆置(头插法)
	
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> key;
		Headinsert(l2,key);
	}
	
	out(l2);
	
	
	cout << "链表的合并两个递增的合成一个递减的\n" ;
	// 4.链表的合并两个递增的合成一个递减的
	List l3;
	List l4;
	List ls;
	Init(l3);
	Init(l4);
	Init(ls);

	cin >> n >> m;
	
	for(int i=1;i<=n;i++){
		cin >> key;
		Tailinsert(l3,key);
	}
	
	for(int i=1;i<=m;i++){
		cin >> key;
		Tailinsert(l4,key);
	}
	
	out(l3);
	out(l4);
	
	Lunionn(l3,l4,ls);
	
	out(ls);

	
}
/*
5
4 2 1 3 -3
*/

/*

4 4
1 3 5 8
1 5 7 8

*/

顺序栈:进制转换(16进制内)

#include
using namespace std;

/*栈的应用
1.输入一个十进制数 , 利用栈转化成 n 进制数

注意栈是基于线性表实现的 , 栈是可扩容的

top 指针永远放在栈顶元素的下一个位置上

*/

const int stacksize = 100;//基础量
const int newsize = 50;//增量

typedef struct{
	int *base;
	int top;//栈顶指针
	int nowsize;//栈的容量
}Sqstack;


char mp[17] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void Initstack(Sqstack &S){
	
	S.base = (int *)malloc(stacksize * sizeof(int));
	if(!S.base){
		cout << "创建失败\n" ;
		return ; 
	} 
	
	S.top = 0;
	S.nowsize = stacksize;
}//类似于顺序表

int isempty(Sqstack S){
	if(S.top == 0){
		return 1;
	}else{
		return 0;
	}
}

int Stacklen(Sqstack S){
	return S.top;
}

void Adddate(Sqstack &S,int c){
	if(S.top >= S.nowsize){
		int* newbase = (int *)realloc(S.base , (S.nowsize + newsize) * sizeof(int));
		S.base = newbase;
		S.nowsize += newsize;
	}
		
	S.base[S.top++] = c;
	return ;
}

void Stacktop(Sqstack &S){
	cout << mp[S.base[--S.top]];
	return ;
}

void Stackout(Sqstack S){
	while(!isempty(S)){
		Stacktop(S);
	}
}

int date , base;


int main(){

	Sqstack S1;
	
	Initstack(S1);
	
	cout << "请输入一个十进制数:\n";
	
	cin >> date;
	
	cout << "请输入一个进制(16进制以内):\n";
	
	cin >> base;
	
	
	while(date){
		
		Adddate(S1 , date % base);
		date /= base;
	}
	
	
	Stackout(S1);


	return 0;
}

循环队列:舞伴配对问题

. 利用循环队列模拟舞伴配对问题:在舞会上,男、女各自排成一队。舞会开始时。依次从男队和女队的队头各出一人配成舞伴。如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。b. 假设初始男、女人数及性别已经固定,舞会的轮数从键盘输入。试模拟解决上述舞伴配对问题。要求:从屏幕输出每一轮舞伴配对名单,如果在该轮有未配对的,能够从屏幕显示下一轮第一个出场的未配对者的姓名。

#include
using namespace std;

/*
循环队列是基于线性表实现的

front 队头指针放在队头上
rear  队尾指针放在队尾的下一个

拿出一个空间区分队空和队伍满

*/

const int Qmaxsize = 100;
int n1 , n2;
string name;

typedef struct{
	
	string *base;
	int front , rear;
		
}Cqueue; 

Cqueue Q1 , Q2;


void InitCqueue(Cqueue &Q){
	
	Q.base = (string *)malloc(Qmaxsize * sizeof(string));
	if(!Q.base){
		cout << "创建失败\n";
		return ;
	}
	
	Q.front = Q.rear = 0;
	
	return ;
}

int IsEmpty(Cqueue &Q){
	if(Q.rear == Q.front) return 1;
	return 0;
}

int IsFull(Cqueue &Q){
	if((Q.rear + 1) % Qmaxsize == Q.front) return 1;
	return 0;
}

void Enqueue(Cqueue &Q , string name){
	if(IsFull(Q)){
		cout << "队列已满\n";
		return ;
	}
	Q.base[Q.rear] = name;
	
//	cout << Q.base[Q.rear] << "\n" ; 
	
	Q.rear = (Q.rear + 1) % Qmaxsize;
	
	// cout << Q.rear << "\n" ;
}

void Dequeue(Cqueue &Q){
	if(IsEmpty(Q)){
		cout << "队列为空\n";
		return ;
	}
	cout << Q.base[Q.front];
	Q.front = (Q.front + 1) % Qmaxsize;
}


void Input(){

	InitCqueue(Q1);
	InitCqueue(Q2);
	
	cout << "请输入男生人数:\n";
	cin >> n1;
	cout << "请输入男生姓名:\n";
	for(int i=1;i<=n1;i++){
		cin >> name;
		Enqueue(Q1 , name);
	}
	cout << "请输入女生人数:\n";
	cin >> n2;
	cout << "请输入女生姓名:\n";
	for(int i=1;i<=n2;i++){
		cin >> name;
		Enqueue(Q2 , name);
	}
}

void Play(){
	
	int n;
	
	cout << "请输入要进行的轮数:\n";
	
	cin >> n;
	
	int min1 = min(n1 , n2);
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=min1;j++){
			
			cout << "本轮匹配的是:\n";
			cout << Q1.base[Q1.front] << " " << Q2.base[Q2.front] << "\n" ;
			Q1.front = (Q1.front + 1) % n1;
			Q2.front = (Q2.front + 1) % n2;			
		}
		if(min1 == n2){
			cout << "第" << i << "轮未匹配成功的的人是:";
			cout << Q1.base[Q1.front] << "\n";
		}else{
			cout << "第" << i << "轮未匹配成功的的人是:\n";
			cout << Q2.base[Q2.front] << "\n" ;
		}
	}
	
	
}


int main(){

	Input();

    Play();

	return 0;
}

顺序栈:表达式求值

②输入一个表达式,表达式中只包含整数和加、减、乘、除四种双目运算符,计算给定表达式的值。
(这里需要用double 进行处理 , 但是我实在懒得改了)

#include
using namespace std;

/*栈的应用
1.输入一个十进制数 , 利用栈转化成 n 进制数

注意栈是基于线性表实现的 , 栈是可扩容的

top 指针永远放在栈顶元素的下一个位置上

*/

const int stacksize = 100;//基础量
const int newsize = 50;//增量

typedef struct{
	int *base1;
	char *base2;
	int top;//栈顶指针
	int nowsize;//栈的容量
}Sqstack;

Sqstack S1 , S2;
map<char,int>mp;//定义优先级
int ans = 0;

void Initstack1(Sqstack &S){
	
	S.base1 = (int *)malloc(stacksize * sizeof(int));
	if(!S.base1){
		cout << "创建失败\n" ;
		return ; 
	} 
	
	S.top = 0;
	S.nowsize = stacksize;
}//类似于顺序表

void Initstack2(Sqstack &S){
	
	S.base2 = (char *)malloc(stacksize * sizeof(char));
	if(!S.base2){
		cout << "创建失败\n" ;
		return ; 
	} 
	
	S.top = 0;
	S.nowsize = stacksize;
}//类似于顺序表

int isempty(Sqstack S){
	if(S.top == 0){
		return 1;
	}else{
		return 0;
	}
}

int Size(Sqstack S){
	return S.top;
}

void Adddate1(Sqstack &S,int c){
	if(S.top >= S.nowsize){
		int* newbase = (int *)realloc(S.base1 , (S.nowsize + newsize) * sizeof(int));
		S.base1 = newbase;
		S.nowsize += newsize;
	}
		
	S.base1[S.top++] = c;
	return ;
}

void Adddate2(Sqstack &S,char c){
	if(S.top >= S.nowsize){
		char* newbase = (char *)realloc(S.base2 , (S.nowsize + newsize) * sizeof(char));
		S.base2 = newbase;
		S.nowsize += newsize;
	}
		
	S.base2[S.top++] = c;
	return ;
}

void Pop(Sqstack &S){
	S.top--;
	return ;
}

void Input(){
	
	mp['+'] = 0;
	mp['-'] = 0;
	mp['*'] = 1;
	mp['/'] = 1;
	
	Initstack2(S2);
	Initstack1(S1);
	
	cout << "请输入表达式:\n";
	
	string s;
	
	cin >> s;
	
	int len = s.size() , ans = 0;
	
	for(int i=0;i<len;i++){
		if(s[i] != '+' && s[i] != '-' && s[i] != '*' && s[i] != '/' && s[i] != '='){
			ans = ans * 10 + (s[i] - '0');
		}else{
			
//			cout << ans << " " << s[i] << "\n" ;
			
			Adddate1(S1 , ans);
			Adddate2(S2 , s[i]);
			ans = 0;
		}
	}
	
	Pop(S2);//把等号弹出去
	
	
}


void check(){
	
	int num1 , num2 , num3 , tmp ;
	char c1 , c2;
	
	while(Size(S1) > 2){
		num1 = S1.base1[--S1.top];
		num2 = S1.base1[--S1.top];
		num3 = S1.base1[--S1.top];
		c1 = S2.base2[--S2.top];
		c2 = S2.base2[--S2.top];
		
		
//		cout << num1 << " " << num2 << " " << num3 << "\n" ; 
		
		if(mp[c2] > mp[c1]){
			if(c2 == '*') tmp = num3 * num2;
			if(c2 == '/') tmp = num3 / num2;
			Adddate1(S1 , tmp);
			Adddate1(S1 , num1);
			Adddate2(S2 , c1);
		}else{
			if(c1 == '*') tmp = num1 * num2;
			if(c1 == '/') tmp = num2 / num1;
			if(c1 == '+') tmp = num2 + num1;
			if(c1 == '-') tmp = num2 - num1;
			
//			cout << tmp << "\n" ;
			
			Adddate1(S1 , num3);
			Adddate1(S1 , tmp);
			Adddate2(S2 , c2);
		}
	}
	
	num1 = S1.base1[--S1.top];
	num2 = S1.base1[--S1.top];
	c1 = S2.base2[S2.top];
	if(c1 == '*') tmp = num1 * num2;
	if(c1 == '/') tmp = num2 / num1;
	if(c1 == '+') tmp = num2 + num1;
	if(c1 == '-') tmp = num2 - num1;
	
	cout << "表达式的值是:" << tmp ;
}


int main(){
	
	Input();
	
	check();
	
	
	return 0;
}

二叉树

数据结构 の 实验(Update : 22.11.15)_第3张图片

#include
using namespace std;

const int Qmaxsize = 1000;
//----------------------------------------------------------------------------------------//
struct BTNode{
	char data;
	struct BTNode *Lchild,*Rchild;
};
typedef struct BTNode* Bt;
//----------------------------------------------------------------------------------------//
struct Queue{
	Bt *base;
	int front,rear; 
};
//----------------------------------------------------------------------------------------//
struct Stack{
	Bt *base;
	int top;//栈顶指针
	int nowsize;//栈的容量
};
//----------------------------------------------------------------------------------------//
void InitQueue(Queue &Q){
	
	Q.base = (Bt *)malloc(Qmaxsize * sizeof(Bt));
	Q.front = Q.rear = 0;
	return ;
}

void InitStack(Stack &S){
	
	S.base = (Bt *)malloc(Qmaxsize * sizeof(Bt));
	S.top = 0;
	S.nowsize = Qmaxsize;
}

int QEmpty(Queue &Q){
	if(Q.rear == Q.front) return 1;
	return 0;
}

/*
二叉链表类似于链表
AB#DF##G##C#E##
*/


//二叉链表的建立  前序建立
void BuildBT(Bt &B){
	char c ;
	cin >> c;
	if(c == '#'){
		B = NULL;
	}else{
		B = (Bt)malloc(sizeof(Bt));
		B -> data = c;
		BuildBT(B -> Lchild);
		BuildBT(B -> Rchild);
	}
}

//递归前序
void PreOrder(Bt B){
	
	if(B == NULL) return ;
	cout << B -> data << " ";
	PreOrder(B -> Lchild);
	PreOrder(B -> Rchild);
}

//递归中序
void InOrder(Bt B){
	
	if(B == NULL) return ;
	InOrder(B -> Lchild);
	cout << B -> data << " ";
	InOrder(B -> Rchild);
}

//递归后序
void PostOrder(Bt B){
	
	if(B == NULL) return ;
	PostOrder(B -> Lchild);
	PostOrder(B -> Rchild);
	cout << B -> data << " ";
}

void Dequeue(Queue &Q){
	
	cout << Q.base[Q.front] -> data << " ";
	Q.front = (Q.front + 1) % Qmaxsize;
}

void Enqueue(Queue &Q , Bt B){
	
	Q.base[Q.rear] = B;
	Q.rear = (Q.rear + 1) % Qmaxsize;
}

void BFS(Queue &Q){
	
	while(!QEmpty(Q)){
		Bt tmp = Q.base[Q.front];
		Dequeue(Q);
		if(tmp -> Lchild != NULL) Enqueue(Q , tmp -> Lchild);
		if(tmp -> Rchild != NULL) Enqueue(Q , tmp -> Rchild);
	}
}

void SPush(Stack &S,Bt B){
	
	S.base[S.top++] = B;
	return ;
}

int SEmpty(Stack S){
	if(S.top == 0)
		return 1;
	else
		return 0;
}

int STop(Stack &S,Bt &e){
	if(S.top == 0)
	return 0;
	e = S.base[S.top-1];
	return 1;	
} 


void SPop(Stack &S,Bt &e){
	e = S.base[--S.top];
	return ;
} 

void fInOrder(Bt B){
	
	if(B == NULL) return ;
	Stack s1;
	Bt p;
	InitStack(s1);
	SPush(s1,B);
	
	while(!SEmpty(s1)){
		
		while(STop(s1 , p) && p) SPush(s1 , p -> Lchild);
		
		SPop(s1 , p);
	
		if(!SEmpty(s1)){
			SPop(s1 , p);
			cout << p -> data << " ";
			SPush(s1 , p -> Rchild);
		}
	}
}

int cnt = 0;

void Getcount(Bt B){
	
	if(B == NULL) return ;
	if(B -> Lchild == NULL && B -> Rchild == NULL) cnt++;
	Getcount(B -> Lchild);
	Getcount(B -> Rchild);
}

int BTDepth(Bt B){
	int L , R;
	if(B == NULL) return 0;
	else{
		L = BTDepth(B -> Lchild);
		R = BTDepth(B -> Rchild);
		return max(L , R) + 1;
	}
}



int main(){
	
	Bt b1;
	//----------------------------------------------------------------------------------------//
	cout << "请输入二叉树字符串 , 用 # 表示虚节点:\n";
	BuildBT(b1);
	//----------------------------------------------------------------------------------------//
	cout << "递归前序遍历序列:\n";
	InOrder(b1);
	cout << "\n" ;
	//----------------------------------------------------------------------------------------//
	cout << "非递归前序遍历序列:\n";
	fInOrder(b1);
	cout << "\n" ;
	//----------------------------------------------------------------------------------------//
	cout << "层次遍历序列:\n";
	Queue q1;
	InitQueue(q1);
	Enqueue(q1,b1);
	BFS(q1);
	cout << "\n" ;
	//----------------------------------------------------------------------------------------//
	cout << "叶子节点总数:\n";
	cnt = 0;
	Getcount(b1);
	cout << cnt << "\n";
	//----------------------------------------------------------------------------------------//
	cout << "二叉树深度:\n";
	int ans = BTDepth(b1);
	cout << ans << "\n" ;



	return 0;
}

tips : 写的时候默认栈和队列不会发生特殊情况(栈空,栈内存不够之类)
还有就是记住这种定义:

数据结构 の 实验(Update : 22.11.15)_第4张图片

二叉树申请空间:
B = (Bt)malloc(sizeof(Bt));
栈和队列申请空间:

Q.base = (Bt *)malloc(Qmaxsize * sizeof(Bt));
S.base = (Bt *)malloc(Qmaxsize * sizeof(Bt));

Bt 已经是指针,定义栈和队列还要加一个 * 是为了后面书写方便 , 记住这种写法;

部分参考自 -> 二叉树

查找

(1)实验要求:

掌握常用的查找方法,了解各种查找方法的过程及其依据的原则,并掌握各种查找方法的效率的分析方法。

(2)实验内容:

必做:随机产生一组m到n之间的一组整数,根据这一组整数完成如下操作:

建立一个顺序表,输入一个关键字,对该表进行顺序查找和折半查找。

#include
using namespace std;
#define Listsize 100

typedef struct node{
	int* base; //基地址
	int len;   //表长
	int size;  //容量
}Sqlist;

void InitSqlist(Sqlist &L){
	L.base = (int *)malloc( Listsize * sizeof(int) );
	if(!L.base){
		puts("初始化失败!");
		return ;
	}
	L.len = 0;
	L.size = 100;
}

//尾插函数
void TailInsert(Sqlist &L ,int key){
	
	//扩容 , 每次给 100 个内存空间
	if(L.len == L.size){
		int* newbase = (int *)realloc(L.base , (L.size + Listsize) * sizeof(int) );
		if(!newbase){
			puts("扩容失败!");
			return ;
		}
		
		L.base = newbase;
		L.size += Listsize;
						
	}
	
	L.base[++L.len] = key;
}

void out(Sqlist L){
	for(int i=1;i<=L.len;i++){
		cout << L.base[i] << " ";
	}
	cout << "\n" ;
}

//随机产生 15个 2 位正整数
void go(Sqlist &L){
	for(int i=1;i<=15;i++){
		int key = rand() % 90 + 10;
		TailInsert(L , key);
	}
}


void find(Sqlist L , int key){
	for(int i=1;i<=L.len;i++){
		if(L.base[i] == key){
			cout << key << " 查找成功\n";
			return ;
		}
	}
	cout << key << " 查找失败\n" ;
	return ;
}

void sort(Sqlist &L){
	
	int n = L.len;
	
	for(int i=1;i<n;i++){//排几趟
		for(int j=1;j<=n-i;j++){//搜几个数 , 注意边界
			if(L.base[j] > L.base[j+1]){
				swap(L.base[j] , L.base[j+1]);
			}
		}
	}
}

void Bsearch(Sqlist L , int key){
	
	int l = 1 , r = L.len;
	
	int mid = (l + r) / 2;
	
	while(l <= r){
		if(L.base[mid] > key){
			r = mid - 1;
		}else if(L.base[mid] < key){
			l = mid + 1;
		}else{
			cout << key << " 查找成功\n";
			return ;
		}
		mid = (l + r) / 2;
	}
	
	cout << key << " 查找失败\n";
	
	return ;
	
	
}

int main(){
	
	srand(unsigned(time(0)));
	
	/*-----------------------------------------------------*/
	//顺序查找
	Sqlist L1;
	InitSqlist(L1);
	go(L1);
	out(L1);
	int data = L1.base[1];
	find(L1,12);
	find(L1,data);
	/*------------------------------------------------------*/
	//折半查找
	
	sort(L1);
	out(L1);
	
	Bsearch(L1,12);
	Bsearch(L1,data);
	
	/*-------------------------------------------------------*/
	return 0;
}



排序算法

#include
using namespace std;
#define Listsize 100

typedef struct node{
	int* base; //基地址
	int len;   //表长
	int size;  //容量
}Sqlist;

void Init(Sqlist &L){
	L.base = (int *)malloc( Listsize * sizeof(int) );
	if(!L.base){
		puts("初始化失败!");
		return ;
	}
	L.len = 0;
	L.size = 100;
}

void TailInsert(Sqlist &L ,int key){
	
	//扩容 , 每次给 100 个内存空间
	if(L.len == L.size){
		int* newbase = (int *)realloc(L.base , (L.size + Listsize) * sizeof(int) );
		if(!newbase){
			puts("扩容失败!");
			return ;
		}
		
		L.base = newbase;
		L.size += Listsize;
						
	}
	
	L.base[++L.len] = key;
}

void out(Sqlist L){
	for(int i=1;i<=L.len;i++){
		cout << L.base[i] << " ";
	}
	cout << "\n" ;
}

void go(Sqlist &L){
	for(int i=1;i<=15;i++){
		int key = rand() % 90 + 10;
		TailInsert(L , key);
	}
}

void Bubblesort(Sqlist &L){
/*
直接插入排序
把序列分为两部分,一部分是有序序列 , 一部分是无序序列
不断把无序序列中的元素插入有序序列
*/	
	
	int n = L.len;
	
	for(int i=1;i<=n-1;i++){//排几趟
		for(int j=1;j<=n-i;j++){//搜几个数 , 注意边界
			if(L.base[j] > L.base[j+1]){
				swap(L.base[j] , L.base[j+1]);
			}
		}
	}
}

void Insertsort(Sqlist &L){
	
	int n = L.len;
	
	for(int i=2;i<=n;i++){
		L.base[0] = L.base[i];
		bool f = 0;
		for(int j=i-1;j>=1;j--){
			if(L.base[0] < L.base[j]){
				L.base[j+1] = L.base[j];
			}else{
				L.base[j+1] = L.base[0];
				f = 1;
				break;
			}
		}
		
		if(!f) L.base[1] = L.base[0] ;
	}
}

void Quicksort(Sqlist &L,int l,int r){
	
	
	if(l >= r) return ;//快速排序终止标志
	
	int key = L.base[0] = L.base[l];
	int ls = l , rs = r;
	//注意保存一下原始的 l 和 r ,在排序后 l r 发生变化
	while(l < r){
		while(l < r && L.base[r] >= key) r--;//右边
		if(l < r) L.base[l++] = L.base[r];
		while(l < r && L.base[l] <= key) l++;
		if(l < r) L.base[r--] = L.base[l];
	}
	
	L.base[l] = L.base[0];
	
	
	Quicksort(L , ls , l - 1);
	Quicksort(L , l + 1 , rs);
}

void merge(int l,int mid,int r,Sqlist &L , Sqlist &t){
	
	int i = l  , j = mid + 1 , k = l ;
	//模拟归并过程
	while(i <= mid && j <= r){
		if(L.base[i] < L.base[j]) t.base[k++] = L.base[i++];
		else t.base[k++] = L.base[j++];
	}
	while(i <= mid) t.base[k++] = L.base[i++];
	while(j <= r) t.base[k++] = L.base[j++];
	for(int i=l;i<=r;i++) L.base[i] = t.base[i];
}

void mergesort(int l,int r,Sqlist &L , Sqlist &t){
	if(l >= r) return ;
	int mid = (l + r) / 2;
	
	//分离开左右区间
	mergesort(l , mid , L , t);
	mergesort(mid+1 , r , L , t);
	
	//边分离边合并
	merge(l,mid,r,L,t);
}

void Heapadjust(Sqlist &L,int l,int r){
	for(int i=l;i<=r;i++){
		int j = i;
		while(L.base[j] > L.base[j/2] && j != 1) swap(L.base[j],L.base[j/2]) , j /= 2; 
	}
}

void Heapsort(Sqlist &L,int l,int r){
	for(int i=L.len;i>=2;i--){
		Heapadjust(L,1,i);
		swap(L.base[1],L.base[i]);
	}
}

int main(){
	
	srand(unsigned(time(0)));
	//-------------------------------------------------------
	//直接插入排序
	cout << "1.直接插入排序:\n";
	Sqlist L1;
	Init(L1);
	go(L1);
	out(L1);
	Insertsort(L1);
	out(L1);
	//-------------------------------------------------------
	//冒泡排序
	cout << "2.冒泡排序:\n";
	Sqlist L2;
	Init(L2);
	go(L2);
	out(L2);
	Bubblesort(L2);
	out(L2);
	//-------------------------------------------------------
	//快速排序
	cout << "3.快速排序:\n";
	Sqlist L3;
	Init(L3);
	go(L3);
	out(L3);
	Quicksort(L3,1,15);
	out(L3);
	//-------------------------------------------------------
	//堆排序
	cout << "4.堆排序:\n";
	Sqlist L4;
	Init(L4);
	go(L4);
	out(L4);
	Heapsort(L4,1,15);
	out(L4);
	//-------------------------------------------------------
	//归并排序
	cout << "5.归并排序:\n";
	Sqlist L5 , t;
	Init(L5);Init(t);
	go(L5);go(t);
	out(L5);
	mergesort(1,15,L5,t);
	out(L5);
	//-------------------------------------------------------
	return 0;
}



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