2020年春安工程网课数据结构代码笔记


顺序表代码c实现:

#include<stdio.h>
#include<Windows.h>
#define LIST_INIT_SIZE 5
#define LIST_ADD_SIZE 1
typedef int ElemType;// 顺序表内容元素的类型,这么写完全是为了好维护

typedef struct {
	ElemType *elem;
	int length;//表中最后一个元素的位置tail
	int size; //顺序表的容量
}Sqlist;
void addElem(Sqlist &L, ElemType e) {
	if (L.length == L.size) {
		printf("扩若了");
		ElemType *temp = (ElemType *)realloc(L.elem, (L.size + LIST_ADD_SIZE)*sizeof(ElemType));
		if (!temp) {
			exit(-1);
		}
		L.elem = temp;
		L.size += LIST_ADD_SIZE;
	}
	L.elem[L.length] = e;
	L.length++;
	

}
void printList(Sqlist &L) {
	printf("打印整个个顺序表\n");
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.elem[i]);
	}
	printf("\n");
}
void  init(Sqlist &L) {
	L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if (!L.elem) {
		exit(-1);
	}
	L.length = 0;
	L.size = LIST_INIT_SIZE;
}
void getElem(Sqlist &L, int i, ElemType &e) {
	if (i<1 || i>L.length) {
		return;
	}
	e = L.elem[i - 1];
}
void insert(Sqlist &L, int i, ElemType e) {
	if (i<1 || i>L.length+1) {
		return;
	}
	if (L.length == L.size) {
		ElemType *temp = (ElemType *)realloc(L.elem, (L.size + LIST_ADD_SIZE));
		if (!temp) {
			exit(-1);
		}
		L.elem = temp;
		L.size += LIST_ADD_SIZE;
	}
	for (int m = L.length - 1; m >= i - 1; --m) {//从后往前
		L.elem[m + 1] = L.elem[m];
	}
	L.elem[i-1] = e;
	L.length++; 
}
void del(Sqlist &L, int i) {
	if (i<1 || i>L.length ) {
		return;
	}
	ElemType e = L.elem[i - 1];
	for (int m = i; m < L.length; m++)
	{
		L.elem[m - 1] = L.elem[m];
	} 
	L.length--;
}
int find(Sqlist &L, ElemType e) {
	int i = 1;
	while (i <= L.length&&L.elem[i - 1] != e) {
		i++;
	}
	if (i > L.length) {
		i = 0;
	}
	return i;
}
int main() {
	Sqlist L;
	printf("测试初始化和添加函数\n");
	init(L);
	addElem(L, 1);
	
	addElem(L, 2);

	addElem(L, 3);
	printList(L);
	/*printf("测试插入函数\n");
	insert(L, 2, 5);
	printList(L);
	printf("测试获取函数\n" );
	int num = 0;
	getElem(L, 1, num);
	printf("%d\n",num);
	printf("测试删除函数\n");
	del(L, 2);
	printList(L);
	printf("测试查找函数\n");
	int index = find(L, 3);
	if (index == 0) {
		printf("没找到\n");
	}
	else {
		printf("%d\n", index);
	}*/



}

链表C语言实现:

#include<stdio.h>
#include<Windows.h>
typedef int E;// 顺序表内容元素的类型,这么写完全是为了好维护

typedef struct HeroNode{
	E value;
	struct  HeroNode *next;
	void toString() {
		printf("%d ", value);
	}
}*LinkedList;
void createList(LinkedList &L) {
	L = (LinkedList)malloc(sizeof(HeroNode));
	L->next = NULL;
	L->value = 0;//其实L的值我们不关心,这一行可以不写
}
void addFromHead(LinkedList &L, HeroNode *p) {//L的位置一直不在动
	p->next = L->next;
	L->next = p;
}
void addFromTail( HeroNode *p,LinkedList &tail) {//tail移动,tail为参数合适
	
	tail->next = p;
	tail = p;//这里p之前一定要置空
}

void printLinkedList(LinkedList L) {
	HeroNode *p = L->next;
	while (p) {
		p->toString();
		p = p->next;
	}
}
int getLength(LinkedList &L) {
	int counts = 0;
	HeroNode *p = L;
	while (p->next) {
		counts++;
		p = p->next;
	}
	return counts;
}
E getElem(LinkedList &L, int i) {
	if (i<1 || i>getLength(L)) {
		return -1;
	}
	int num = 1;
	HeroNode *p = L->next;//1
	while (1&&num<=getLength(L)) {
		if (num == i) {
			return p->value;
		}
		num++;
		p = p->next;
	}
	return -1;
	

}
void insert(LinkedList &L,int i,HeroNode *p) {
	if (i > getLength(L) + 1 || i <= 0) {
		return ;
	}
	int num = 1;
	HeroNode *temp = L;//1
	while (num <= getLength(L)+1) {
		if (num == i)
		{
			p->next = temp->next;
			temp->next = p;
			break;
		}
		num++;
		temp = temp->next;
	}
	

}
int main() {

	LinkedList L; 
	createList(L);
	HeroNode *p = (LinkedList)malloc(sizeof(HeroNode)); p->value = 5;
	HeroNode *p1 = (LinkedList)malloc(sizeof(HeroNode)); p1->value = 6;
	HeroNode *p2 = (LinkedList)malloc(sizeof(HeroNode)); p2->value = 3;

	addFromHead(L, p); addFromHead(L, p1); addFromHead(L, p2);

	printLinkedList(L);//365,因为是头插法

	LinkedList L1;
	createList(L1);
	LinkedList tail = L1;
	HeroNode *p3 = (LinkedList)malloc(sizeof(HeroNode)); p3->value = 5; p3->next = NULL;
	HeroNode *p4= (LinkedList)malloc(sizeof(HeroNode)); p4->value = 6; p4->next = NULL;
	HeroNode *p5 = (LinkedList)malloc(sizeof(HeroNode)); p5->value = 3; p5->next = NULL;

	addFromTail( p3, tail); addFromTail( p4, tail);// addFromTail(p5, tail);
	printLinkedList(L1);//563
	printf("\n");

	//测试
	printf("%d", getLength(L1));
	printf("%d",getElem(L1, 1)); printf("\n");

	HeroNode *p6= (LinkedList)malloc(sizeof(HeroNode)); p6->value = 89; p6->next = NULL;
	insert(L1, 3, p6);
	printLinkedList(L1);

	return 0;
}

链表c++实现:(感觉简单多了,相较于c)

#include<bits/stdc++.h>
using namespace std;
typedef int E;

class HeroNode {
public:
	E value;
	HeroNode *next;
	HeroNode(E value) {
		this->value=value ;
		this->next = NULL;
	}
	void toString() {
		printf("value=%d ", value);
	}
};
class LinkedList {
	
public:
	
	HeroNode *head = new HeroNode(0);
	
	void addFromHead(HeroNode *p) {//Head的位置一直不在动
		p->next = head->next;
		head->next = p;
	}
	void printLinkedList() {
		HeroNode *p = head->next;
		while (p) {
			p->toString();
			p = p->next;
		}
	}
	int getLength() {
		int counts = 0;
		HeroNode *p = head;
		while (p->next) {
			counts++;
			p = p->next;
		}
		return counts;
	}
	E getElem( int i) {
		if (i<1 || i>getLength()) {
			return -1;
		}
		int num = 1;
		HeroNode *p = head->next;//1
		while (1 && num <= getLength()) {
			if (num == i) {
				return p->value;
			}
			num++;
			p = p->next;
		}
		return -1;


	}
	void insert(int i,HeroNode *p) {
	if (i > getLength() + 1 || i <= 0) {
		return ;
	}
	int num = 1;
	HeroNode *temp = head->next;//1
	while (num <= getLength()+1) {
		if (num == i)
		{
			p->next = temp->next;
			temp->next = p;
			break;
		}
		num++;
		temp = temp->next;
	}
	

}
};
int main() {
	LinkedList list;
	HeroNode *h1=new HeroNode(8);
	HeroNode *h2 = new HeroNode(5);
	HeroNode *h3 = new HeroNode(3);
	list.addFromHead(h1);
	list.addFromHead(h2);
	list.addFromHead(h3);
	list.printLinkedList();
	cout<<list.getLength();
	cout << list.getElem(2);
	HeroNode *h4 = new HeroNode(78);
	list.insert(1, h4);
	list.printLinkedList();
}

链表处理多项式c++实现:

#include<bits/stdc++.h>
using namespace std;
class Node {
public:
	int c;//changshu
	int z;//zhishuxiang
	Node *next=NULL;
	Node(int c, int z) {
		this->c = c;
		this->z = z;
	}
	void toString() {
		printf("%dx^%d", c, z);
	}
};
class NodeList {
public:
	Node *head = new Node(0, 0);
	Node *tail = head;
	Node* getFirstNode() {
		return head->next;
	}
	void addFromTail(Node *p) {//tail移动,tail为参数合适
		tail->next = p;
		tail = p;//这里p之前一定要置空
	}
	void printNodeList() {
		printf("f(x)=");
		Node *p = head->next;
		while (p) {
			if (p->c == 0) {
				p = p->next;
				continue;
			}
			if (p->c > 0&&p!=head->next) {
				printf("+");
			}
			p->toString();
			p = p->next;
		}
		printf("\n");
	}
	void addBetweenList(Node *fa,Node *fb) {
		while (fa&&fb) {
			if (fa->z < fb->z) {
				tail->next = fa;
				tail = fa;
				fa = fa->next;
			}
			else if (fa->z > fb->z) {
				tail->next = fb;
				tail = fb;
				fb = fb->next;
			}
			else if(fa->z +fb->z==0){
				fa = fa->next; fb = fb->next;
			}
			else {
				Node *temp=new Node(fa->c+fb->c,fa->z);
				tail->next = temp;
				tail = temp;
				fa = fa->next; fb = fb->next;
			}
		}

		//将可能剩余的残留合并
		if (fa != NULL) {
			tail->next = fa;
			tail = fa;
		}
		else if (fb!=NULL) {
			tail->next = fb;
			tail = fb;
		}

	}
};
int main() {
	NodeList L,L1,L2;
	Node *n1 = new Node(1,0);
	Node *n2 = new Node(-10, 6);
	Node *n3 = new Node(2, 8);
	Node *n4 = new Node(7, 14);
	Node *n5 = new Node(-1, 4);
	Node *n6 = new Node(10, 6);
	Node *n7 = new Node(-3, 10);
	Node *n8 = new Node(8, 14);
	Node *n9 = new Node(4, 18);
	Node *n10 = new Node(7, 20);
	L.addFromTail(n1); L.addFromTail(n2); L.addFromTail(n3); L.addFromTail(n4);
	L1.addFromTail(n5);	L1.addFromTail(n6);	L1.addFromTail(n7);	L1.addFromTail(n8);	L1.addFromTail(n9); L1.addFromTail(n10);
	L.printNodeList(); L1.printNodeList();
	Node* fa = L.getFirstNode();
	Node* fb = L1.getFirstNode();
	L2.addBetweenList(fa, fb);
	L2.printNodeList();
}

栈 c++模板实现:

#include<bits/stdc++.h>

using namespace std;



template<class T>

class Stack

{

public:

Stack() {

arr = new T(size);

}

bool isEmpty() {

return head == tail;

}

bool isFull() {

return tail  == size-1;

}

void push(T p) {

if (isFull()) {

cout << "满了" << endl;

return;

}

tail++;

arr[tail] = p;


}

T pop() {

if (isEmpty()) {

cout << "空了" << endl;

return NULL;

}

T temp = arr[tail];

tail--;

return temp;

}

T peek() {

return arr[tail];

}

void printStack() {

for (int i = head+1; i <=tail; i++)

{

cout << arr[i]<<" ";

}

}



private:

int head = -1;

int tail = -1;

T *arr;

int size = 2;

};

int main() {

Stack<int>s;

s.push(1);

s.push(2);


s.printStack();

cout<<s.peek();

}

进制转化c++实现:

#include<bits/stdc++.h>

using namespace std;

int main() {

int  D,result ;
cin >>D>>result;
stack<int>s;

while (result != 0) {

    s.push(result % D);

    result = result / D;

}
if (s.empty()) {
    cout << 0;
}
while (!s.empty()) {
    cout << s.top();
    s.pop();
}
return 0;

}


字符串表达式括号使用是否合法检测C++实现:

c++实现:

#include<bits/stdc++.h>
using namespace std;
bool isLeft(char c) {
	return (c == '{' || c == '[' || c == '(');
}
bool isRight(char c) {
	return (c == '}' || c == ']' || c == ')');
}
bool isMatch(char c, char d) {
	if (c == '{'&&d == '}') {
		return true;
	}
	if (c == '['&&d == ']') {
		return true;
	}
	if (c == '('&&d == ')') {
		return true;
	}
	return false;
}
bool isStrLegal(char *arr) {
	stack<char> s;
	int len = strlen(arr);
	for (int i = 0; i < len; i++)
	{
		if (isLeft(arr[i])) {
			s.push(arr[i]);
		}
		else if (isRight(arr[i])) {
			char temp = s.top();
			if (isMatch(temp, arr[i])) {
				s.pop();
			}
			else {
				return false;
			}
		}
	}
	return s.empty();
}
int main() {
	char arr[] = "{(})";
	int len = sizeof(arr);
	if (isStrLegal(arr)) {
		cout << "合法" << endl;
	}
	else {
		cout << "不合法" << endl;
	}
}

//稀疏数组c++这一节课其实挺绕的,自己多思考(更新于2020.2.24)

#include<iostream>
//稀疏数组c++
using namespace std;
#define SIZE 100
typedef struct {
	int i, j;//非零行列下标
	int value;
	void toString() {
		cout << i << " " << j << " " << value << endl;
	}
}Ele;
typedef struct S{
	Ele data[SIZE];
	int m, n, t;
	void printLikeArr() {
		cout << "打印稀疏矩阵,还原的普通矩阵" << endl;
		int p = 0;
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++) {
				if (data[p].i == i && data[p].j== j) {
					//cout << data[p].value << " ";
					printf("%d ",data[p].value);
					p++;
				}
				else {
					cout << 0 << " ";
				}
			}
			cout << endl;
		}
	}
	void transpose(S &B) {
		int q = 0;
		B.m = this->n; B.n = this->m; B.t = this->t;
		for (int col = 0; col < this->n; col++)
		{
			for (int p = 0; p < this->t; p++)
			{
				if (this->data[p].j == col) {
					B.data[q].i = this->data[p].j;
					B.data[q].j = this->data[p].i;
					B.data[q].value= this->data[p].value;
					q++;
				}
			}
		}
	}
	void quickTranspose(S &B) {
		int q ;
		int num[100] = { 0 }; //统计当前稀疏数组每一列非零元素的个数
		int pos[100] = { 0 };//每列首个非零元素在转置矩阵中的索引
		B.m = this->n; B.n = this->m; B.t = this->t;
		for (int p = 0; p <this->t; p++)//完成初始化
		{
			num[this->data[p].j]++;
		}
		for (int j = 1;  j < this->n;  j++)//完成初始化,注意从一开始
		{
			pos[j] = pos[j - 1] + num[j - 1];//比如第一列两个元素,第二列的肯定放在0+2的位置
		}
		for (int p = 0; p < this->t; p++)//遍历当前稀疏数组每一个数据
		{
			Ele temp = this->data[p];//按顺序取出来一个
			q = pos[temp.j];//获得这个元素所在列的首个非零元素的,注意(除非是j第一次被使用),不然其实pos【j】里面内容已经被++修改了
			B.data[q].i = temp.j;
			B.data[q].j = temp.i;
			B.data[q].value = temp.value;
			pos[temp.j]++;
		}
	}
}sparseArray;

int main() {
	int arr[6][7] = {0};
	int counts = 0;
	int p = 0;//索引
	arr[0][1] = 12; arr[0][2] = 9; arr[2][0] = -3;//自定义初始化一个二维数组
	arr[2][5] = 14; arr[3][2] = 24; arr[4][1] = 18; arr[5][0] = 15; arr[5][3] = -7;
	for (int i = 0; i < 6; i++)
	{
		for (int j = 0; j < 7; j++) {
			if (arr[i][j] != 0) {
				counts++;
			}
		}
	}
	sparseArray s;
	s.m = 6; s.n = 7; s.t = counts;//完成稀疏矩阵功能行的初始化
	for (int i = 0; i < 6; i++)

	{
		for (int j = 0; j < 7; j++) {
			if (arr[i][j] != 0) {
				s.data[p].i = i;
				s.data[p].j = j;
				s.data[p].value = arr[i][j];
				p++;
			}
		}
	}
	for (int i = 0; i < counts; i++)
	{
		s.data[i].toString();
	}
	s.printLikeArr();

	sparseArray B;//转置矩阵
	s.transpose(B);
	cout << "输出s的转置稀疏矩阵B" << endl;
	for (int i = 0; i < counts; i++)
	{
		B.data[i].toString();
	}
	B.printLikeArr();

	sparseArray C;
	s.quickTranspose(C);
	C.printLikeArr();


}

c++实现二叉树的创建和前序遍历

#include<iostream>
using namespace std;
class Node {
public:
	char value;Node * left;Node * right;
	Node(char v) {
		value = v;
	}
	void toString() {
		cout << value << " ";
	}
	void preOrder() {
		this->toString();
		if (this->left != NULL) 
			this->left->preOrder();
		if (this->right != NULL) 
			this->right->preOrder();
	}
};
class NodeTree {
public:
	Node * root;
	void creatTree(Node* &node) {//先序输入创建二叉树
		char ch;cin >> ch;
		if (ch == '#') 
			node = NULL;
		else {
			node = new Node(ch);
			creatTree(node->left);
			creatTree(node->right);
		}
	}
	void preOrder() {//先序遍历,还有两种,重复不写了
		if (root==NULL)
		{
			cout << "二叉树为空" << endl;
			return;
		}
		else 
			this->root->preOrder();
	}
};
int main() {
	NodeTree *tree=new NodeTree();
	tree->creatTree(tree->root);//由头结点创建
	tree->preOrder();
}

线索化二叉树c++实现

#include<bits/stdc++.h>
using namespace std;


class newHeroNode {
public:
	string name; int no;
	newHeroNode *left=NULL;
	newHeroNode *right=NULL;
	int leftType;//0是左子树,1是前驱节点
	int rightType;//0是右子树,1是后继节点
	newHeroNode(int no, string name);
	void toString();
	void infixOrder();
};

newHeroNode::newHeroNode(int no, string name)
{
	this->no = no;
	this->name = name;
}

void newHeroNode::toString()
{
	cout << no << " " << name << endl;
}

void newHeroNode::infixOrder()
{
	if (this->left != NULL) {
		this->left->infixOrder();
	}
	this->toString();
	if (this->right != NULL) {
		this->right->infixOrder();
	}
}
class ThreadedBinaryTree {
public:
	newHeroNode *root;//根节点
	newHeroNode *pre;//指向当前节点的前驱节点
	void setRoot(newHeroNode *root) {
		this->root = root;
	}
	void threadedNodes(newHeroNode *node) {
		if (node == NULL) {
			return;
		}
		threadedNodes(node->left);
		if (node->left==NULL)
		{
			node->left = pre;
			node->leftType = 1;
		}
		if (pre!=NULL&&pre->right==NULL)
		{
			pre->right = node;
			pre->rightType = 1;
		}
		pre = node;
		threadedNodes(node->right);
	}
	 void infixOrder() { 
		 if (this->root != NULL) {
			 this->root->infixOrder();
		 } else { 
			 cout<<"二叉树为空,无法遍历"<<endl; 
		 }
	 }
	  void threadedList() {
		 newHeroNode *node = root;
		 while (node != NULL) {
			 while (node->leftType == 0) {
				 node = node->left;
			 }
				 node->toString();
			 if (node->rightType == 1) {
				 node = node->right;
				 node->toString();
			 }
			 node = node->right;
		 }
	 }
	
};
int main() {
	newHeroNode *h1 = new newHeroNode(1, "松江");
	newHeroNode *h2 = new newHeroNode(3, "卢俊义");
	newHeroNode *h3 = new newHeroNode(6, "林冲");
	newHeroNode *h4 = new newHeroNode(8, "吴用");
	newHeroNode *h5 = new newHeroNode(10, "张飞");
	newHeroNode *h6 = new newHeroNode(14, "江左");
	h1->left=h2;
	h1->right=h3;
	h2->left=h4;
	h2->right=h5;
	h3->left=h6;

	ThreadedBinaryTree *tbt = new ThreadedBinaryTree();
	tbt->setRoot(h1);
	tbt->infixOrder();
	tbt->threadedNodes(h1);
	tbt->threadedList();
	
}

二叉排序树的添加创建和查找,删除c++实现:

#include<bits/stdc++.h>
using namespace std;

class Node {
public:
	int value;
	Node *left=NULL,*right=NULL;
	Node(int value) {
		this->value = value;
	}
	void toString() {
		cout << value << " ";
	}
	Node* search(int value) {//查找某个节点
		if (value == this->value)
			return this;
		else if (value < this->value) {
			if (this->left == NULL) {
				return NULL;
			}
			return this->left->search(value);
			
		}
		else {
			if (this->right == NULL)
				return NULL;
			return this->right->search(value);
		}
	}
	Node* searchParent(int value) {//某节点的父亲节点
		if ((this->left != NULL && this->left->value == value)
			|| (this->right != NULL && this->right->value == value)) {
			return this;
		}
		else {
			if (value < this->value&&this->left != NULL)
				return this->left->searchParent(value);
			else if (value >= this->value&&this->right != NULL)
				return this->right->searchParent(value);
			else
				return NULL;
		}

	}
	void add(Node *node) {
		if (node == NULL)
			return;
		if (node->value <= this->value) {
			if (this->left == NULL)
				this->left = node;
			else
				this->left->add(node);
		}
		else{
			if (this->right == NULL)
				this->right = node;
			else
				this->right->add(node);
		}
	}
	void infixOrder() {
		if (this->left != NULL)
			this->left->infixOrder();
		this->toString();
		if (this->right != NULL)
			this->right->infixOrder();
	}
		

};
class BinarySortTree {
public:
	Node *root=NULL;
	void add(Node *node) {
		if (root == NULL)
			root = node;
		else {
			root->add(node);
		}
	}
	void infixOrder() {
		if (root == NULL) {
			cout << "kong"; return;
		}
		else {
			root->infixOrder();
		}
		cout << endl;

	}
	Node* search(int value) {
		if (root == NULL) { return NULL; }
		else { return root->search(value); }
	}
	Node* searchParent(int value) {
		if (root == NULL) { return NULL; }
		else { return root->searchParent(value); }
	}
	//编写方法:
	//1. 返回的 以 node 为根结点的二叉排序树的最小结点的值 
	//2. 删除 node 为根结点的二叉排序树的最小结点
	/**** @param node 传入的结点(当做二叉排序树的根结点) *
	@return 返回的 以 node 为根结点的二叉排序树的最小结点的值 */
	int delRightTreeMin(Node* node) {
		Node* target = node;
		while (target->left != NULL) {
			target = target->left; 
		}//这时 target 就指向了最小结点
		 //删除最小结点 
		delNode(target->value);
		return target->value;
	}

//删除节点的思路
/*
第一种情况:
删除叶子节点 (比如:2, 5, 9, 12)
思路
(1) 需求先去找到要删除的结点  targetNode
(2)  找到targetNode 的 父结点 parent
(3)  确定 targetNode 是 parent的左子结点 还是右子结点
(4)  根据前面的情况来对应删除
左子结点 parent.left = null
右子结点 parent.right = null;
第二种情况: 删除只有一颗子树的节点 比如 1
思路
(1) 需求先去找到要删除的结点  targetNode
(2)  找到targetNode 的 父结点 parent
(3) 确定targetNode 的子结点是左子结点还是右子结点
(4) targetNode 是 parent 的左子结点还是右子结点
(5) 如果targetNode 有左子结点
5. 1 如果 targetNode 是 parent 的左子结点
parent.left = targetNode.left;
5.2  如果 targetNode 是 parent 的右子结点
parent.right = targetNode.left;
(6) 如果targetNode 有右子结点
6.1 如果 targetNode 是 parent 的左子结点
parent.left = targetNode.right;
6.2 如果 targetNode 是 parent 的右子结点
parent.right = targetNode.right


情况三 : 删除有两颗子树的节点. (比如:7, 3,10 )
思路
(1) 需求先去找到要删除的结点  targetNode
(2)  找到targetNode 的 父结点 parent
(3)  从targetNode 的右子树找到最小的结点
(4) 用一个临时变量,将 最小结点的值保存 temp = 11
(5)  删除该最小结点
(6)  targetNode.value = temp
*/
	void delNode(int value) {
		if (root == NULL) {
			return;
	
		}
		else {
			Node *targetNode = search(value);
			if (targetNode == NULL)
				return;
			if (root->left == NULL && root->right == NULL) {//只有一个节点,而且还找到了
				root = NULL; return;
			}

			Node *parent = searchParent(value);
			//第一种情况,叶子节点
			if (targetNode->left == NULL && targetNode->right == NULL) {
				if (parent->left != NULL && parent->left->value == value)
					parent->left = NULL;
				else if (parent->right != NULL && parent->right->value == value)
					parent->right = NULL;
			}
			//第三种情况
			else if (targetNode->left != NULL && targetNode->right != NULL) {
				int minVal = delRightTreeMin(targetNode->right);//找右边子树最小的
				targetNode->value = minVal;
			}

			//第二种情况,删除只有一边子树的节点
			else {
				if (targetNode->left != NULL) {
					if (parent != NULL) {
						if (parent->left->value==value) {
							parent->left =targetNode->left;
						}
						if(parent->right->value == value) 
						{
							parent->right = targetNode->left;
						}
					}
					else {
						root = targetNode->left;
					}
				}
				else {
					if (parent != NULL) {
						if (parent->left->value == value) {
							parent->left = targetNode->right;
						}
						if (parent->right->value == value)
						{
							parent->left = targetNode->right;
						}
					}
					else {
						root = targetNode->right;
					}
				}
				
			}
		}
	}


};
int main() {
	int arr[] = { 7,3,10,12,5,1,9 };
	BinarySortTree bst;
	for (int i = 0; i < 7; i++)
	{
		bst.add(new Node(arr[i]));
	}
	bst.infixOrder();
	bst.delNode(12);
	bst.delNode(5);
	bst.delNode(10);
	bst.delNode(2);
	bst.delNode(3);
	bst.delNode(9);
	bst.delNode(7);
	bst.delNode(1);
	


	bst.infixOrder();

}

​平衡二叉树(二叉搜索树)c++
只是对二排排序树的改进,让搜索效率变高,
所以对树的高度进行了平衡:

#include<bits/stdc++.h>
using namespace std;

class Node {
public:
	int value;
	Node *left = NULL, *right = NULL;
	Node(int value) {//初始化节点的值
		this->value = value;
	}
	void toString() {//打印
		cout << value << " ";
	}
	int Heigth() {// 返回 以该结点为根结点的树的高度
		return max(left == NULL ? 0 : left->Heigth(), right == NULL ? 0 : right->Heigth()) + 1;
	}
	int leftHeight() {// 返回左子树的高度
		if (left == NULL)
			return 0;
		return left->Heigth();
		
	}
	int rightHeight() {
		if (right == NULL)
			return 0;
		return right->Heigth();
	}
	void leftRotate() {
		Node *newNode = new Node(value);
		newNode->left = left;
		newNode->right = right->left;
		value = right->value;
		right = right->right;
		left = newNode;
	}
	/*
		主义思考
	*/
	void rightRotate() {
		Node *newNode = new Node(value);
		newNode->right = right;
		newNode->left = left->right;
		value = left->value;
		left = left->left;
		right = newNode;

	}
	void add(Node *node) {
		if (node == NULL)
			return;
		if (node->value <= this->value) {
			if (this->left == NULL)
				this->left = node;
			else
				this->left->add(node);
		}
		else {
			if (this->right == NULL)
				this->right = node;
			else
				this->right->add(node);
		}
		//当添加完一个结点后,如果: (右子树的高度-左子树的高度) > 1 , 左旋转
		if (rightHeight() - leftHeight() > 1) {
			//如果它的右子树的左子树的高度大于它的右子树的右子树的高度
			if (right != NULL && right->leftHeight() > right->rightHeight()) {
				//先对右子结点进行右旋转
				right->rightRotate();
				//然后在对当前结点进行左旋转
				leftRotate(); //左旋转..
			}
			else {
				//直接进行左旋转即可
				leftRotate();
			}
			return; //必须要!!!
		}
		//当添加完一个结点后,如果 (左子树的高度 - 右子树的高度) > 1, 右旋转
		if (leftHeight() - rightHeight() > 1) {
			//如果它的左子树的右子树高度大于它的左子树的高度
			if (left != NULL && left->rightHeight() > left->leftHeight()) {
				//先对当前结点的左结点(左子树)->左旋转
				left->leftRotate();
				//再对当前结点进行右旋转
				rightRotate();
			}
			else {
				//直接进行右旋转即可
				rightRotate();
			}
		}
	}
	void infixOrder() {
		if (this->left != NULL)
			this->left->infixOrder();
		this->toString();
		if (this->right != NULL)
			this->right->infixOrder();
	}
};
class AVLTree {
public:
	Node *root = NULL;
	Node* getRoot() {
		return root;
	}
	void add(Node *node) {
		if (root == NULL)
			root = node;
		else {
			root->add(node);
		}
	}
	void infixOrder() {
		if (root == NULL) {
			cout << "kong"; return;
		}
		else {
			root->infixOrder();
		}
		cout << endl;

	}
};
int main() {
	int arr[] = { 10, 11, 7, 6, 8, 9 };
	AVLTree avl;
	for (int i = 0; i < 6; i++)
	{
		avl.add(new Node(arr[i]));
	}
	avl.infixOrder();
	cout << avl.getRoot()->leftHeight()<<endl;
	cout << avl.getRoot()->rightHeight() << endl;
	cout << avl.getRoot()->value;

}

图的相关操作及深度优先遍历和广度优先遍历

#include<bits/stdc++.h>
using namespace std;
class Graph {//Graph图
private:
	vector<string> vertexList;//(vertex顶点)顶点集合
	int **edges;//存储图对应的邻结矩阵,二维矩阵
	int numOfEdges;//表示边的个数
	bool *isVisited;//记录某个节点有没有被访问过
public:
	Graph(int n) {//构造器
		edges = new int*[n];
		for (int i = 0; i < n; i++) {
			edges[i] = new int[n];
			for (int j = 0; j < n; j++)
			{
				edges[i][j] = 0;
			}
		}
			
		numOfEdges = 0;
		isVisited = new bool[n];
		memset(isVisited, false,n);
		
		
	}
	//图中常用的方法
	
	 int getNumOfVertex() {//返回顶点的个数
		return vertexList.size();
	 }
	 void showGraph() {//显示图对应的矩阵
		 for (int i = 0; i < vertexList.size(); i++) {
			 for (int j = 0; j < vertexList.size(); j++)
			 {
				 cout << edges[i][j];
			 }
			 cout << endl;
		 }
	 }
	
	 int getNumOfEdges() { //得到边的数目
		 return numOfEdges;
	 }
	 //返回结点i(下标)对应的数据 0->"A" 1->"B" 2->"C"
	 string getValueByIndex(int i) {
		 return vertexList[i];
	 }
	 //返回v1和v2的权值
	 int getWeight(int v1, int v2) {
		 return edges[v1][v2];
	 }
	 //插顶点
	 void insertVertex(string vertex) {
		 vertexList.push_back(vertex);
	 }
	 //添加路径对应关系,用邻接矩阵记录
	 void insertEdge(int v1, int v2, int weight) {
		 edges[v1][v2] = weight;
		 edges[v2][v1] = weight;
		 numOfEdges++;
	 }
	 //获得,当前行的第一个非零元素,即与当前顶点有关联的第一个顶点
	 int getFirstNeighbor(int index) {
		 for (int j = 0; j < vertexList.size(); j++) {
			 if (edges[index][j] > 0) {
				 return j;
			 }
		 }
		 return -1;
	 }
	 //获当前v1行的,v2列后面的第一个非零元素
	 int getNextNeighbor(int v1, int v2) {
		 for (int j = v2 + 1; j < vertexList.size(); j++) {
			 if (edges[v1][j] > 0) {
				 return j;
			 }
		 }
		 return -1;
	 }
	 //深度优先遍历算法
	//i 第一次就是 0
	 void dfs(int i) {
		 //首先我们访问该结点,输出
		 cout << getValueByIndex(i) << "->";
		 //将结点设置为已经访问
		 isVisited[i] = true;
		 //查找结点i的第一个邻接结点w
		 int w = getFirstNeighbor(i);
		 while (w != -1) {//说明有
			 if (!isVisited[w]) {
				 dfs(w);
			 }
			 //如果w结点已经被访问过
			 w = getNextNeighbor(i, w);
		 }

	 }
	 //对dfs 进行一个重载, 遍历我们所有的结点,并进行 dfs
	  void dfs() {
		 //遍历所有的结点,进行dfs[回溯]
		 for (int i = 0; i < getNumOfVertex(); i++) {
			 if (!isVisited[i]) {
				 dfs(i);
			 }
		 }
	 }
	  //广度优先
	  void bfs(int i) {
		  int u; // 表示队列的头结点对应下标
		  int w; // 邻接结点w
		  //队列,记录结点访问的顺序  
		  queue<int> q;
		  cout << getValueByIndex(i) << "->";
		  isVisited[i] = true;
		  q.push(i);
		  while (!q.empty()) {
			  u = q.front(); q.pop();
			  w = getFirstNeighbor(u);
			  while (w!=-1)
			  {
				  if (!isVisited[w]) {
					  cout << getValueByIndex(w) << "->";
					  isVisited[w] = true;
					  q.push(w);
				  }
				  w = getNextNeighbor(u, w);
			  }
		  }
	  }
	  //遍历所有的结点,都进行广度优先搜索
	  void bfs() {
		  for (int i = 0; i < getNumOfVertex(); i++) {
			  if (!isVisited[i]) {
				  bfs(i);
			  }
		  }
	  }
};
int main() {
	//测试一把图是否创建ok
	int n = 5;  //结点的个数
	string Vertexs[] = { "1", "2", "3", "4", "5", "6", "7", "8" };
	Graph graph(8);
	for (string e:Vertexs)
		graph.insertVertex(e);
		graph.insertEdge(0, 1, 1);
		graph.insertEdge(0, 2, 1);
		graph.insertEdge(1, 3, 1);
		graph.insertEdge(1, 4, 1);
		graph.insertEdge(3, 7, 1);
		graph.insertEdge(4, 7, 1);
		graph.insertEdge(2, 5, 1);
		graph.insertEdge(2, 6, 1);
		graph.insertEdge(5, 6, 1);
		graph.showGraph();
		graph.bfs();
	
	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值