上学时写了一半的代码,留着吧。

复习书本:张宪超 《数据结构、算法及应用》
第一章、绪论
1.结构的分类
线性结构、树形结构、图结构
2.数据的存储结构
顺序方法-数组(访问优势)
链接方法-链表(修改优势)
索引方法-顺序存储的推广(提高检索效率,存储的是指向目标的指针)
散列方法-索引法的推广
3.渐进分析
4.时间复杂度分析,最好、最坏和平均情况(概率*花销的累加和)
5.空间开销
第二章、线性表
1.线性表的存储结构-[顺序表(数组,定长),链式存储结构(链表)]
2.线性表的运算-[创建实例,析构函数,增删改查,辅助操作]
3.行优先顺序表,列优先顺序表
4.单链表,双链表,循环链表
5.顺序栈,链式栈
6.顺序队列,链式队列
7.字符串~~(未写)~~
8.
第三章、数
1.概念
树有n个节点,n为0称为空结构/空树
兄弟节点:有共同父节点
叶子节点:无子节点
分支节点:非叶子结点
结点的度:孩子结点的数量
树的度:所有结点度的最大值
结点的层数:根节点的层数为0
树的深度:结点层数的最大值
数的高度:树的深度加1
有序树,无序树,森林
2.性质及表示方法
n结点度为m的树,最小高度为 上取整(lg(n(m-1)+1) / lg(m))
树形表示法,文氏图表示法,凹入标表示法,嵌套括号表示法
3.二叉树相关概念
所有结点度小于等于2为二叉树(空树也为二叉树)
完全二叉树:除最后一层外所有层结点达到最大值(叶子结点只能在最后一层和次大两层出现)
对于任意二叉树,度数为0的结点比度数
为2的结点多一个
4.二叉树的遍历
1)广度优先遍历。使用队列储存节点。队列头部节点寻找子节点并放到队列结尾。
2)前序遍历(先根遍历) 先访问根节点,将该节点右节点压入栈中,遍历左子树,重复过程,直到无左子树。弹出栈顶,继续遍历。
3)中序遍历(中根遍历) 将根节点压入栈中,并不断将根节点的左子节点压入栈中,直到没有左子节点。弹出栈顶并访问该节点,然后将该节点的右子节点压入栈,重复上面过程。
4)后序遍历(后根遍历) 从根节点向左搜索并压入栈中,直到没有节点。读取栈顶节点,如果没有右节点或者右节点访问过,就访问栈顶节点并弹出,否则将右节点压入栈中,并重复上面过程。

单链表(有头结点)

#include<iostream>
using namespace std;
template<class T>
class LinkNode{
public :
	T data;
	LinkNode<T>*link;
};
template<class T>
class LinkList{
private:
	LinkNode<T>*head, *tail;
	LinkNode<T>*currPtr;
	int size;
public:
	LinkList();
	~LinkList();
	int getSize()const;
	bool isEmpty()const;
	void insertTail(T &item);
	T deleteHead();
	void clear();
	void show();
	T getHeadValue();
	void swapNext(LinkNode<T>*current, LinkNode<T>*father);
	LinkNode<T>*getHeadLink();
};
template<class T>
LinkNode<T>* LinkList<T>::getHeadLink(){
	return head;
}
template<class T>
void LinkList<T>::swapNext(LinkNode<T>*current,LinkNode<T>*father){
	LinkNode<T>*next = current->link;
	if (next == NULL)return;
	LinkNode<T>*end = next->link;
	father->link = next;
	next->link = current;
	current->link = end;
}
template<class T>
LinkList<T>::~LinkList(){
	clear();
}
template<class T>
void LinkList<T>::clear(){
	LinkNode<T>*temp = head->link;
	while (temp != NULL){
		LinkNode<T>*next = temp->link;
		LinkNode<T>*now = temp;
		delete now;
		temp = next;
	}
	head->link = NULL;
	tail = head;
	size = 0;
}
template<class T>
T LinkList<T>::deleteHead(){
	if (head->link == NULL){
		cout << "error" << endl;
		return 0;
	}
	LinkNode<T>*temp = head->link;
	head->link = temp->link;
	if (tail == temp){
		tail = head;
	}
	size--;
	T res = temp->data;
	delete temp;
	return res;
}
template<class T>
bool LinkList<T>::isEmpty()const{
	return (size > 0 ? false : true);
}
template<class T>
int LinkList<T>::getSize()const{
	return size;
}
template<class T>
void LinkList<T>::insertTail(T &item){
	size++;
	LinkNode<T>* node = new LinkNode<T>();
	node->data = item; node->link = NULL;
	tail->link = node;
	tail = tail->link;
}
template<class T>
void LinkList<T>::show(){
	LinkNode<T>*temp = head->link;
	while (temp != NULL){
		cout << temp->data << " ";
		temp = temp->link;
	}
}
template<class T>
T LinkList<T>::getHeadValue(){
	return head->link->data;
}
template<class T>
LinkList<T>::LinkList(){
	LinkNode<T> *headNode = new LinkNode<T>();
	headNode->link = NULL;
	head = tail = headNode;
	size = 0;
}
int main(){
	LinkList<int> s;
	
	int n = 1;
	for (int i = 0; i < n; i++){
		int temp;
		cin >> temp;
		s.insertTail(temp);
	}
	LinkNode<int> *link = s.getHeadLink();
	
	s.swapNext(link->link, link);
	
	cout << s.isEmpty() << endl;
	cout << s.getSize() << endl;
	
	s.show();
	s.clear();
	s.deleteHead();
}

双链表(有头结点)

#include<iostream>
using namespace std;
template<class T>
class Node{
public:
	T data;
	Node<T>*next, *before;
	Node(){
		next = before = NULL;
	}
};
template<class T>
class List{
private:
	Node<T>*head, *tail;
	int size;
public:
	List();
	~List();
	int getSize();
	void insert(int pos,T&item);
	void show();
	void deletePos(int pos);
	int findPos(T&item);
	
	
};
template<class T>
int List<T>::getSize(){
	return size;
}
template<class T>
List<T>::List(){
	Node<T>*node = new Node<T>();
	head = tail = node;
	size = 0;
}
template<class T>
void List<T>::insert(int pos,T&item){
	if (pos > size)return;
	Node<T>*temp = head;
	for (int curr = 0; curr < pos; curr++){
		temp = temp->next;
	}
	Node<T>*last = new Node<T>();
	last->data = item; last->before = temp; last->next = temp->next;
	temp->next = last;
	
	if (pos == size){
		tail = last;
		size++;
		return;
	}
	size++;
	last->next->before = last;
}
template<class T>
void List<T>::show(){
	Node<T>*temp = head->next;
	while (temp != NULL){
		cout << temp->data << " ";
		temp = temp->next;
	}
	cout << endl;
}
template<class T>
void List<T>::deletePos(int pos){
	if (pos > size)return;
	
	Node<T>*temp = head;
	for (int curr = 0; curr < pos; curr++){
		temp = temp->next;
	}
	Node<T>*now = temp->next;
	temp->next = now->next;
	if (pos < size-1){
		now->next->before = temp;
	}
	delete now;
	size--;
}
template<class T>
int List<T>::findPos(T&item){
	Node<T>*temp = head->next;
	int position = 0;
	while (temp != NULL){
		if (temp->data == item)return position;
		temp = temp->next;
		position++;
	}
	return -1;
}

template<class T>
List<T>::~List(){
	int position = 0;
	while (position < size){
		deletePos(position);
		position++;
	}
}
int main(){
	int n;
	cin >> n;
	List<int> s;
	for (int i = 0; i < n; i++){
		int temp;
		cin >> temp;
		s.insert(s.getSize(),temp);
	}
	s.show();
	int p = 10;
	s.insert(0, p);
	s.show();

	s.deletePos(1);
	s.show();
	int m = 23;
	cout << s.findPos(m) << endl;
	return 0;
}

####循环双链表

#include<iostream>
using namespace std;
template<class T>
class Node{
public:
	T data;
	Node<T>*next, *before;
	Node(){
		next = before = NULL;
	}
};
template<class T>
class List{
private:
	Node<T>*head, *tail;
	int size;
public:
	List();
	~List();
	int getSize();
	void insert(int pos, T&item);
	void show();
	void deletePos(int pos);
	int findPos(T&item);


};
template<class T>
int List<T>::getSize(){
	return size;
}
template<class T>
List<T>::List(){
	Node<T>*node = new Node<T>();
	head = tail = node;
	node->next = node->before = node;

	size = 0;
}
template<class T>
void List<T>::insert(int pos, T&item){
	if (pos > size)return;
	Node<T>*temp = head;
	for (int curr = 0; curr < pos; curr++){
		temp = temp->next;
	}
	Node<T>*last = new Node<T>();
	last->data = item; last->before = temp; last->next = temp->next;
	temp->next = last;

	if (pos == size){
		tail = last;
		size++;
		return;
	}
	size++;
	last->next->before = last;
}
template<class T>
void List<T>::show(){
	Node<T>*temp = head->next;
	while (temp != head){
		cout << temp->data << " ";
		temp = temp->next;
	}
	cout << endl;
}
template<class T>
void List<T>::deletePos(int pos){
	if (pos > size)return;

	Node<T>*temp = head;
	for (int curr = 0; curr < pos; curr++){
		temp = temp->next;
	}
	Node<T>*now = temp->next;
	temp->next = now->next;
	
	now->next->before = temp;
	
	delete now;
	size--;
}
template<class T>
int List<T>::findPos(T&item){
	Node<T>*temp = head->next;
	int position = 0;
	while (temp != head){
		if (temp->data == item)return position;
		temp = temp->next;
		position++;
	}
	return -1;
}

template<class T>
List<T>::~List(){
	int position = 0;
	while (position < size){
		deletePos(position);
		position++;
	}
}
int main(){
	int n;
	cin >> n;
	List<int> s;
	for (int i = 0; i < n; i++){
		int temp;
		cin >> temp;
		s.insert(s.getSize(), temp);
	}
	s.show();
	int p = 10;
	s.insert(0, p);
	s.show();

	s.deletePos(0);
	s.show();
	int m = 23;
	cout << s.findPos(m) << endl;
	return 0;
}

顺序栈

#include<iostream>
using namespace std;
template<class T>
class Stack{
public:
	void clear();
	bool push(T&item);
	bool pop(T&item);
	bool getTop(T&item);
	bool isEmpty();
};
template<class T>
class arrStack:public Stack<T>{
private:
	int maxSize;
	int top;
	T *st;
public:
	arrStack(int size){
		top = -1;
		maxSize = size;
		st = new T[maxSize];
	}
	~arrStack(){
		delete[] st;
	}
	bool push(T&item){
		if (top + 1 == maxSize)return false;
		top++;
		st[top] = item;
		return true;
	}
	bool pop(T&item){
		if (top == -1)return false;
		item = st[top--];
		return true;
	}
	bool getTop(T&item){
		if (top == -1)return false;
		item = st[top];
		return true;
	}
	void clear(){
		top = -1;
	}
	bool isEmpty(){
		return (top == -1);
	}
	void show(){
		int temp = 0;
		while (temp <= top){
			cout << st[temp++] << " ";
		}
		cout << endl;
	}
};

int main(){
	arrStack<int> *str = new arrStack<int>(10);
	int n;
	cin >> n;
	int arr[10];
	for (int i = 0; i < n; i++){
		cin >> arr[i];
		str->push(arr[i]);
	}
	int temp = -1;
	str->show();
	str->pop(temp);
	str->show();
	cout << temp << endl;
	str->getTop(temp);
	cout << temp;
	str->clear();
	str->show();
	cout<<str->isEmpty();
}

链式栈

#include<iostream>
using namespace std;
template<class T>
class Stack{
public:
	void pop();
	T getTop();
	void push(T item);
	void show();
	void clear();
};
template<class T>
class Node{
public:
	T data;
	Node<T>*next;
	Node(){ next = NULL; }
};
template<class T>
class linkStack :public Stack<T>{
private:
	Node<T>*head, *tail;
public:
	linkStack(){
		head = tail = NULL;
	}
	void push(T item){
		Node<T>*node = new Node<T>();
		node->next = head; node->data = item;
		head = node;
		if (head == NULL){
			tail = node;
		}
	}
	void show(){
		Node<T>*node = head;
		while (node != NULL){
			cout << node->data << " ";
			node = node->next;
		}
		cout << endl;
	}
	void clear(){
		Node<T>*node = head;
		while (node != NULL){
			Node<T>*Next = node->next;
			delete node;
			node = Next;
		}
		head = tail = NULL;
	}
	
	void pop(){
		if (head == NULL)return;
		Node<T>*node = head;
		head = head->next;
		delete node;
	}
	T getTop(){
		if (head == NULL)return 0;
		return head->data;
	}
};
int main(){
	int n;
	cin >> n;
	linkStack<int>*s = new linkStack<int>();
	s->show();
	for (int i = 0; i < n; i++){
		int temp;
		cin >> temp;
		s->push(temp);
	}
	s->show();
	s->pop();
	s->show();
	cout << s->getTop() << endl;
	s->clear();
	s->show();

}

求字符串的最长相同前后缀长度

#include<iostream>
using namespace std;
#define N 40
int F[N];
char *B;
// a  b a a b  b a b a c
// 0  0 1 1 2  0 1 2 3 
void getLongest(){
	//Fi为0到i串的最长相同前后缀长度
	F[0] = 0;
	for (int i = 1; i < strlen(B); i++){
		//获取第i位前的字符串的先后缀长度
		int len = F[i - 1];
		//找到加上新字符后的能构成最长前后缀的长度
		while ((B[len] != B[i]) && (len>0)){
			len = F[len - 1];
		}
		//找到
		if (B[len] == B[i])F[i] = len + 1;
		else F[len] = 0;
	}
}
int main(){
	A = new char[N];
	B = new char[N];
	cin >> B;
	getLongest();
	for (int i = 0; i < strlen(B); i++){
		cout << F[i] << " ";
	}
}

二叉树先中后序遍历,栈式和递归式及广度优先

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
#define lson (rt<<1|1)
#define rson ((rt+1)<<1)
#define N 100
int arr[N];
void buildTree(int n){
	//15 1 2 3 0 4 0 5 0 0 6 7 0 0 0 8
	for (int i = 0; i < n; i++){
		cin >> arr[i];
		
	}
}
void bfsShow(int n){
	int rt = 0;
	queue<int> q;
	q.push(rt);
	while (!q.empty()){
		rt = q.front(); q.pop();
		if (arr[rt] == 0)continue;
		cout << arr[rt] << " ";
		 
		 
		q.push(lson);
		q.push(rson);
	}
	cout << endl;
}
void dfsPreShow(int n,int rt){
	 
	 
	if (arr[rt] == 0)return;
	cout << arr[rt] << " ";
	dfsPreShow(n, lson);
	dfsPreShow(n, rson);
}
void dfsMidShow(int n, int rt){
	 
	 
	if (arr[rt] == 0)return;
	dfsMidShow(n, lson);
	cout << arr[rt] << " ";
	dfsMidShow(n, rson);
}
void dfsBackShow(int n, int rt){
	 
	 
	if (arr[rt] == 0)return;
	dfsBackShow(n, lson);
	dfsBackShow(n, rson);
	cout << arr[rt] << " ";
}
void StackPreShow(int n){
	stack<int> s;
	int rt = 0;
	while (arr[rt]!=0 || !s.empty()){
		if (arr[rt] != 0){
			cout << arr[rt] << " ";
			s.push(rson);
			rt = lson;
		}
		else{
			rt = s.top(); s.pop();
		}
	}
	cout << endl;
	
}
void StackMidShow(int n){
	stack<int>s;
	int rt = 0;
	while (arr[rt] != 0 || !s.empty()){
		if (arr[rt] != 0){
			s.push(rt);
			rt = lson;
		}
		else{
			rt = s.top(); s.pop();
			cout << arr[rt] << " ";
			rt = rson;
			
		}
	}
}
void StackBackShow(int n){
	int par = -1;
	int rt = 0;
	stack<int>s;
	while (1){
		while (arr[lson] != 0){
			s.push(rt);
			par = rt;
			rt = lson;
		}
		//没有右节点或者访问过右节点,
		//输出当前值,根变到栈顶,弹出栈顶
		//当前根为栈顶的左子点
		while (arr[rson] == 0 || par == rt * 2 + 2){
			cout << arr[rt] << " ";
			if (s.empty())return;
			par = rt;
			rt = s.top();
			s.pop();
		}
		s.push(rt);
		rt = rson;

	}
}
int main(){
	int n;
	cin >> n;
	buildTree(n);
	bfsShow(n);
	cout << endl;
	dfsPreShow(n, 0); cout << endl;
	StackPreShow(n); cout << endl;
	dfsMidShow(n, 0); cout << endl;
	StackMidShow(n); cout << endl;
	dfsBackShow(n, 0); cout << endl;
	StackBackShow(n); cout << endl;
}

先序建立的二叉搜索树

c 数据结构与算法ppt 数据结构与算法分析c++pdf_c++


一种是插入方法,沿着根比大小

一种直接找左右节点

####平衡二叉树建树、删除、插入、查找

#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
/*
*平衡二叉树插入、删除、查找
*
*
*
*/
class node{
public:
	
	int val;
	int h, bf;
	node*left, *right;
	node(int x){ val = x; left = right = NULL; h = 1; bf = 0; }
	void copyVal(node*t){
		this->val = t->val;
	}
};
class tree{
public:
	node*root;
	stack<node*>s;
	tree(){ root = NULL; }
	int getH(node*rt){
		if (rt == NULL)return 0;
		int lh, rh;
		lh = rh = 0;
		if (rt->left)lh = rt->left->h;
		if (rt->right)rh = rt->right->h;
		return max(lh, rh) + 1;
	}
	int getBf(node*rt){
		if (rt == NULL)return 0;
		return getH(rt->right) - getH(rt->left);
	}
	node* RRrotate(node*rt){
		node*right = rt->right;
		rt->right = right->left;
		right->left = rt;

		rt->h = getH(rt);
		rt->bf = getBf(rt);
		right->h = getH(right);
		right->bf = getBf(right);
		return right;
	}
	node* LLrotate(node*rt){
		node*left = rt->left;
		rt->left = left->right;
		left->right = rt;

		rt->h = getH(rt);
		rt->bf = getBf(rt);
		left->h = getH(left);
		left->bf = getBf(left);
		return left;
	}
	node* LRrotate(node*rt){
		node*l = rt->left;
		rt->left = RRrotate(l);
		return LLrotate(rt);
	}
	node* RLrotate(node*rt){
		node*r = rt->right;
		rt->right = LLrotate(r);
		return RRrotate(rt);
	}
	node*insert(node*rt,int val){
		if (rt == NULL){ return rt = new node(val); }
		node*t = rt;
		if (val < rt->val){
			rt->left = insert(rt->left, val);
			t = rt->left;
		}
		else{
			rt->right = insert(rt->right, val);
			t = t->right;
		}
		rt->h = getH(rt);
		rt->bf = getBf(rt);
		if (abs(rt->bf) <= 1)return rt;
		else
		if (rt->bf == 2 && t->bf == 1)return RRrotate(rt);
		else if (rt->bf == 2 && t->bf == -1)return RLrotate(rt);
		else if (rt->bf == -2 &&t->bf == -1)return LLrotate(rt);
		else return LRrotate(rt);
		
		
	}
	void BFSshow(){
		if (root == NULL){
			cout << "empty" << endl;
		}
		queue<node*>q;
		q.push(root);
		while (!q.empty()){
			node*t = q.front(); q.pop();
			if (t->left)q.push(t->left);
			if (t->right)q.push(t->right);
			cout << t->val << " ";
		}
		cout << endl;
	}
	void preOrder(){
		stack<node*>s;
		node*t = root;
		while (t || !s.empty()){
			if (t){
				cout << t->val << " ";
				s.push(t->right);
				t = t->left;
			}
			else{
				t = s.top(); s.pop();

			}
		}
		cout << endl;
	}
	void InOrder(){
		stack<node*>s;
		node*t = root;
		while (t || !s.empty()){
			if (t){
				s.push(t);
				t = t->left;
			}
			else{
				t = s.top(); s.pop();
				cout << t->val << " ";
				t = t->right;
			}
		}
		cout << endl;
	}
	void bacOrder(){
		stack<node*>s;
		node*pre = NULL;
		node*t = root;
		while (t){
			while (t->left){
				s.push(t);
				pre = t;
				t = t->left;
			}
			while (t->right == NULL || pre == t->right){
				cout << t->val << " ";
				pre = t;
				if (s.empty()){
					cout << endl;
					return;
				}
				t = s.top(); s.pop();
			}
			s.push(t);
			t = t->right;

		}
		cout << endl;
	}
	node*&find(int val){
		node*t = root;
		while (t){
			if (val < t->val){
				if (t->left&&t->left->val == val)return t->left;
				else t = t->left;
			}
			else if (val>t->val){
				if (t->right&&t->right->val == val)return t->right;
				else t = t->right;
			}
			else return t;

		}
		t = NULL;
		return t;
	}
	void build(){
		int arr[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
		for (int i = 0; i < sizeof(arr)/sizeof(int); i++){
			root=insert(root,arr[i]);
		}
		BFSshow();
	}
	void combineDel(int val){
		node*&t = find(val);
		if (t == NULL)return;
		if (t->left == NULL&&t->right == NULL){
			delete t;
			t = NULL;
		}
		else if (t->left == NULL&&t->right != NULL){
			delete t;
			t = t->right;
		}
		else if (t->right == NULL&&t->left){
			delete t;
			t = t->left;
		}
		else{
			node*p = t->left;
			node*pt = p;
			node*par = t;
			while (p->right){ 
				par = p;
				p = p->right; 
			}
			if (par == t){
				p->right = t->right;
				delete t;
				t->left = p;
			}
			else{
				p->right = t->right;
				
				delete t;
				t = pt;
			
			}
		}
	}
	void copyDel(int val){
		node*&t = find(val);
		node*par = t;
		if (t == NULL)return;
		if (t->left == NULL&&t->right == NULL){
			delete t;
			t = NULL;
		}
		else if (t->left == NULL&&t->right != NULL){
			delete t;
			t = t->right;
		}
		else if (t->right == NULL&&t->left){
			delete t;
			t = t->left;
		}
		else{
			node*p = t->left;
			while (p->right){
				par = p;
				p = p->right;
			}
			t->copyVal(p);
			delete p;
			if (par == t)t->left = NULL;
			else{
				par->right = NULL;
			}
		}
		
		
	}
	void Del(node*&rt,int val){
		if (rt->val == val){
			node*t = rt;
			if (t->left==NULL){
				rt = rt->right;
				if (rt){
					rt->bf = getBf(rt);
					rt->h = getH(rt);
				}
				
				delete t;
			}
			else if (t->right == NULL){
				rt = rt->left;
				if (rt){
					rt->bf = getBf(rt);
					rt->h = getH(rt);
				}
				
				delete t;
			}
			else{
				node*lt = t->left;
				node*par = t;
				while (lt->right){
					par = lt;
					lt = lt->right;
				}
				rt->val = lt->val;
				if (rt->bf == 0){
					Del(rt->left, lt->val);
					rt->bf = getBf(rt);
					rt->h = getH(rt);
				}
				else if (rt->bf == 1){
					Del(rt->left, lt->val);
					rt = RRrotate(rt);
				}
				else if (rt->bf == -1){

					Del(rt->left, lt->val);
					
						if (rt->left->bf <=0){
							rt = LLrotate(rt);
						}
						else {
							rt = LRrotate(rt);
						}
					
					

				}
			}
		}
		else if (val < rt->val){
			Del(rt->left, val);
		}
		else{
			Del(rt->right, val);
		}
	}
	
};
int main(){
	tree t;
	t.build();
	
	
	t.Del(t.root,15);
	t.preOrder();
	t.InOrder();

	
}