数据结构中新学习到的数据存储结构,为了不总是看书上的伪代码,把各种数据结构常用的定义、算法总结在这里,以供之后复习使用。
2020.10.28
1.树与二叉树
①二叉树的存储结构
树的定义一般为递归定义,如果需要溯源到父节点,就定义为三叉链表(包含父节点指针),否则定义为二叉链表(只有左右孩子节点指针)。
struct node
{
int data;//数据域
node *lchild,*rchild,*parent;//左右孩子节点和父节点
};
node *root=NULL;//建树前根节点初始化
如果是二叉链表就把*parent删去即可。
新建一个节点可以使用新建函数:
node* newnode(int x)
{
node *Node=new node;//申请地址
Node->data=x;//赋值
Node->lchild=Node->rchild=NULL;//初始状态没有左右孩子
return Node;//返回节点地址
}
②二叉树节点的查找和修改
在二叉树中查找一个数并将其更改为新的值。
void searchnode(node *root,int x,int newdata)
{
if(root==NULL)//空树,死胡同
return;
if(root->data==x)//找到后更改为新值
root->data=newdata;
searchnode(root->lchild,x,newdata);//往左子树搜索x(递归式)
searchnode(root->rchild,x,newdata);//往右子树搜索x(递归式)
}
③二叉树节点的插入
二叉树结点的插入位置就是数据域在二叉树中查找失败的位置,而这个位置是确定的。因此在递归查找的过程中一定是只根据二叉树的性质来选择左子树或右子树中的一棵进行递归,且最后到达空树(死胡同)的地方就是查找失败的地方,也就是节点需要插入的地方。由此可以得到二叉树节点插入的方法:
void insertnode(node* &root,int x)
{
if(root==NULL){//空树,死胡同,也是新节点应插在的地方
root=newnode(x);
return;
}
if(由性质得x应插在左子树)
insertnode(root->lchild,x);//左子树递归搜索
else
insertnode(root->rchild,x);//右子树递归搜索
}
如果函数中需要需要新建节点,即对二叉树的结构做出修改,就需要加引用。如果仅仅修改当前已有节点的内容,或仅仅是遍历表,就不需要加引用。
在新建节点之后务必令新节点的左右指针为NULL,即表示这个节点目前没有左右子树。
④二叉树的创建
二叉树的创建就是二叉树节点的创建过程,而插入的数据域一般会由题目给出,因此最常见的做法就是把需要插入的数据先存放在数组中,再使用insert函数一个个插入二叉树中,并最终返回二叉树的根节点的指针root。
node* create(int data[],int n)
{
node *root=NULL;//新建空根节点root
for(int i=0;i<n;i++){
insertnode(root,data[i]);插入新节点
}
return root;//返回根节点
}