1.链表
/*链表测试*
int类型 *
单链表 */
#include<bits/stdc++.h>
using namespace std;
struct node{
int key;
node *next;//指向下一个节点
};
typedef node *ptrnode;
typedef ptrnode List;
typedef ptrnode pos;
int isempty(List L){//判空函数
return L->next==NULL;
}
int islast(pos P,List L){//判断是否是最后一个元素;
return P->next==NULL;
}
pos find(List L,int element){//查找元素位置;
pos p=L;
while(p !=NULL and p->key!=element){
p=p->next;
}
if(p->key==element ) return p;
return NULL;
}
pos findpre(List L,int element){//寻找ele的前驱位置;
pos p=L;
while(p->next !=NULL and p->next->key!=element){
p=p->next;
}
if(p->next->key==element ) return p;
return NULL;
}
void Delete(List L,int element){//删除一个元素;
pos tem;
pos p=findpre(L,element);
if(!islast(p,L)){
tem=p->next;
p->next=tem->next;
free(tem);
}
}
void Insert(List L,int element,pos p){//指定位置插入元素;
pos tem;
tem=(ptrnode)malloc(sizeof(node));
if(tem==NULL)//空间溢出;
return;
tem->key=element;
tem->next=p->next;
p->next=tem;
}
void Deletelist(List L){//删除整个链表;
pos p,tem;
p=L->next;
L->next=NULL;
while(p!=NULL){
tem=p->next;
free(p);
p=tem;
}
}
void Travel(List L){//遍历链表;
pos p;
p=L->next;
while(p!=NULL){
cout<<p->key<<endl;//输出值;
p=p->next;
}
}
void Insert_head(List L,int element){//头插;
pos tem=(ptrnode)malloc(sizeof(node));
tem->key=element;
tem->next=L->next;
L->next=tem;
}
int main(){//测试
List L;
L->next=NULL;
for(int i=1;i<=10;i++){
Insert_head(L,i);
}
Travel(L);
Delete(L,5);//删除值为5的节点;
Travel(L);
pos p=find(L,3);//找到值为3的节点
Insert(L,5,p);//在3的后面插入一个节点,值为5;
Travel(L);
return 0;
}
(2)双链表
#include<bits/stdc++.h>
using namespace std;
/*双向链表
int 类型
test*/
struct node{
int key;
node *next;
node *prev;
};
typedef node *ptrnode;
typedef ptrnode List;
typedef ptrnode pos;
bool isempty(List L){//判空;
return L->next==NULL;
}
bool islast(List L,pos P){//判断是否是最后一个;
return P->next==NULL;
}
pos find(List L,int element){//查找元素位置;
pos p=L;
while(p->next!=NULL and p->key!=element){
p=p->next;
}
return p;
}
void Insert(List L,int element,pos p){//按照指定位置插入;
pos tem=(ptrnode)malloc(sizeof(node));
tem->key=element;
tem->prev=p;
tem->next=p->next;
p->next->prev=tem;
p->next=tem;
}
void Delete(List L,int element){//删除指定元素;
pos p=find(L,element);
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
}
void Insert_head(List L,int element){//头插法;
pos tem=(ptrnode)malloc(sizeof(node));
tem->key=element;
tem->next=L->next;
if(L->next!=NULL) L->next->prev=tem;//这里需要注意,假如是第一个插入的元素,则不需要进行这个操作,所以需要特判;
tem->prev=L;
L->next=tem;
}
void Travel_right(List L){//正序遍历;
pos p=L->next;
while(p!=NULL){
cout<<p->key<<endl;
p=p->next;
}
}
int main(){//测试;
List L;
L->next=L->prev=NULL;
for(int i=1;i<=5;i++){
Insert_head(L,i);
}
Travel_right(L);
Delete(L,4);
Travel_right(L);
pos p=find(L,5);
// cout<<p->key<<endl;
// cout<<p->prev->key<<endl;
Insert(L,4,p);
Travel_right(L);
return 0;
}
3.二叉树
/*树_二叉查找树;
test*/
/*二叉查找树性质:
对于一个节点,他的左子树的值小于这个节点的值,
右节点与之相反;*/
#include<bits/stdc++.h>
using namespace std;
/*二叉树建立方式:
完全二叉树可以使用一维数组实现;
其中x的两个子节点分别为2x和2x+1;
比如一共有n个节点,最后一个节点的父节点就是
n/2;
还有一种静态链表的建立方式:
struct node{
int key;
int left;
int right;
}a[node_max];
其中left和right存储的分别是
这个节点的子节点的下标;
*/
struct node{
int key;
node *left;
node *right;
};
typedef node *ptrnode;
typedef ptrnode tree;
typedef ptrnode pos;
tree empty_tree(tree T){//建立一颗空树;
if(T!=NULL){
empty_tree(T->left);
empty_tree(T->right);
free(T);
}
return NULL;
}
pos find(int element,tree T){//查找一个元素的位置;
if(T==NULL) return NULL;
if(element<T->key)
return find(element,T->left);
else if(element>T->key){
return find(element,T->right);
}
else return T;
}
/*因为这种递归方式称为尾递归,所以可以使用非递归实现
//基本框架:
while(T){
if(x<T->key){
T=T->left;
}
if(x>T->key){
T=T->right;
}
else
return T;
}*/
pos find_min(tree T){//寻找最小值
if(T==NULL) return NULL;
else if(T->left==NULL) return T;
else return find_min(T->left);
}
pos find_max(tree T){//寻找最大值;
if(T==NULL) return T;
else if(T->right==NULL) return T;
else return find_max(T);
}
tree Insert(tree T,int element){
if(T==NULL){
T=(ptrnode)malloc(sizeof (node));
T->key=element;
T->left=T->right=NULL;
}
else if(element<T->key)
T->left=Insert(T->left,element);
else if(element>T->key)
T->right=Insert(T->right,element);
return T;
}
tree Delete(tree T,int element){
pos tem;
//if(T==NULL)
if(element<T->key){
T->left=Delete(T->left,element);
}
else if(element>T->key){
T->right=Delete(T->right,element);
}
else if(T->left and T->right){//这个节点有两个子节点的情况;
tem=find_min(T->right);//找到编号最小的右子树;
T->key=tem->key;//替换;
T->right=Delete(T->right,T->key);//删除掉这个节点;
}
else{//只有一个子节点的情况;
tem=T;
if(T->left==NULL) T=T->right;
else if(T->right) T=T->left;
free(tem);
}
return T;
}
void Print(tree T){//输出键值;
cout<<T->key<<endl;
}
void Travel(tree T){//先序遍历;
if(T!=NULL){
Print(T);
Travel(T->left);
Travel(T->right);
}
}
/*先序遍历即先访问根节点然后访问左子树然后右子树;
中序:先访问左子树然后根节点然后右子树;
后序遍历:先访问左子树,然后右子树,然后根节点;
*/
int main(){
tree T=NULL;
for(int i=5;i<=10;i++){
T=Insert(T,i);
}
for(int i=1;i<=4;i++){
T=Insert(T,i);
}
Travel(T);// /
// T=Delete(T,6);
// Travel(T);
return 0;
}