数据结构中的那些树

数据结构

层次建树::

创建一个队列用来暂存结点,先将根结点存入队列中,处理其它结点则需判断双亲结点和本结点是否为虚结点,不是的话就让双亲结点连接本结点,因为根结点没有直接前驱故不参加该步操作,而在开始就做特殊处理。若连接的是右子树,则在连接后要将双亲结点出队,即front++。

pointer* createsequence() {
int front, rear;
char c, j;
pointer *s, *r, *q[20];
front = rear = 0;
while (1) {
/*多写一行输入来过滤回车键*/
scanf("%c", &c);
scanf("%c", &j);
if (c == '#') {
return r;
}
s = (pointer *)malloc(sizeof(pointer));
if (c != '@') {
s->c = c;
s->lchild = s->rchild = NULL;
}
else {
s = NULL;
}
rear++;
q[rear] = s;
/*对根结点特殊处理,因为根结点没有直接前驱*/
if (rear == 1) {
r = s;
front = 1;
}
else {
/*新结点和前一个已有的结点都不为null*/
if (s&&q[front]) {
/*左子树*/
if (rear % 2 == 0) {
q[front]->lchild = s;
}
/*右子树,根据层次序列排序算法需要双亲结点出队*/
else {
q[front]->rchild = s;
front++;
}
}
}
}
}

层次遍历:

front = rear = 0;
if (s == NULL) {
return;
}
rear++;
/*根结点入队1*/
q[rear] = s;
while (front != rear) {
/*根结点出队*/
front++;
/*输出根结点*/
printf("%c ", q[front]->c);
/*获取左右子树,然后通过头指针向后移来输出所有子树*/
if (q[front]->lchild != NULL) {
rear++;
q[rear] = q[front]->lchild;
}
if (q[front]->rchild != NULL) {
rear++;
q[rear] = q[front]->rchild;
}
}
break;

先根建树:

pointer* createfirst() {
pointer *s;
char c; 
scanf("%c", &c);
if (c == '@') {
return NULL;
}
s = (pointer *)malloc(sizeof(pointer));
s->c = c;
s->lchild = createfirst();
s->rchild = createfirst();
return s;
} 

先根遍历:

printf("%c ", s->c);
if (s == NULL) {
return;
}
show(s->lchild,2);
show(s->rchild,2);
break;

当递归到D时,左子树为null则返回进入下一句递归,但其右子树仍然为null,最后就返回s,最多也就建到D,而E和C未添加?

先根+中根建树:

pointer* createfirstandmiddle() {
char Pre[20];
char In[20];
int ps, pe, is, ie;
pointer *s;
int i;
if (ps > pe) {
return NULL;
}
s = (pointer *)malloc(sizeof(pointer));
s->c = Pre[ps];
i = is;
while (In[i] != Pre[ps]) {
i++;
}
s->lchild = createfirstandmiddle(Pre, ps + 1, ps + i - is, In, is, i - 1);
s->rchild = createfirstandmiddle(Pre, ps + i - is + 1, pe, In, i + 1, ie);
return s;
}

遍历算法:

#include<stdio.h>
#include<stdlib.h>
typedef struct node {
int n;
struct node *lchild, *rchild;
}pointer;
pointer *t;
//*创建一棵树
pointer* create() {
pointer *p1, *p2, *p3, *p4;
p1 = (pointer *)malloc(sizeof(pointer));
p2 = (pointer *)malloc(sizeof(pointer));
p3 = (pointer *)malloc(sizeof(pointer));
p4 = (pointer *)malloc(sizeof(pointer));
p1->n = 1;
p1->lchild = p2;
p1->rchild = p3;
p2->n = 2;
p3->n = 3;
p2->lchild = p4;
p2->rchild = NULL;
p4->n = 4;
p3->lchild = NULL;
p3->rchild = NULL;
p4->lchild = NULL;
p4->rchild = NULL;
t = p1;
printf("%d\n", p1);
return t;
}
//递归前序遍历
void show1(pointer *t) {
if (t == NULL)
return;
printf("%d,%d\n", t->n,t);
show(t->lchild);
show(t->rchild);
}
//递归中序遍历
void show2(pointer *t) {
if (t == NULL)
return;
show(t->lchild);
printf("%d,%d\n", t->n,t);
show(t->rchild);
}

//递归后序遍历
void show3(pointer *t) {
if (t == NULL)
return;
show(t->lchild);
show(t->rchild);

printf("%d,%d\n", t->n,t);
}
void main() {
t=create();
show1(t);
}

满二叉树:除最后一层外,每一层上的所有结点都有两个子结点。

完全二叉树:除最后一层外,每一层上的结点数均达到最大值,在最后一层上只缺少右边的若干结点。

链表的应用:

#include<stdio.h>

struct student{

int num;

float score;

struct  Student *next;

}

void main(){

struct Student a,b,c,*head,*p;

a.num=10101;a.score=89.5;

b .num=10102;a.score=99.5;

c.num=10103;a.score=100;

head=&a;

a.next=&b;

b.next=&c;

c.next=null;

p=head;

do{

printf("%ld %5.lf\n,p->num,p->score")

p=p->next;

}while(p!=null);

}

二叉树的遍历:

二叉树的遍历

前序遍历:先遍历根结点,然后遍历左子树,最后遍历右子树。ABDHECFG

中序遍历:先遍历左子树,然后遍历根结点,最后遍历右子树。HDBEAFCG

后根序遍历:先遍历左子树,然后遍历右子树,最后遍历根节点。HDEBFGCA

任意一棵二叉树度数为0的叶子结点总是比度数为2的结点多一个。

在线性表的链式存储结构中,各数据结点的存储序号是不连续的,并且个节点在存储空间中的位置关系和逻辑关系也不一致。

队列的顺序存储结构一般采用循环队列的形式

删除线性表中的数字方法:2.交替扫描,1.一步到位

#include <stdio.h>
typedef char datatype;

typedef struct {
    datatype data[10];
    int n;
}sqlist;

void init(sqlist *p) {
    int i, j;
    for (i = 97, j = 0; i < 108, j<7; i++, j++) {
        p->data[j] = i;
    }
    p->data[7] = 49;
    p->data[8] = 52;
    p->data[9] = 53;
    p->n = 10;
    printf("初始线性表为: ");
    for (j = 0; j < 10; j++) {
        printf("%c  ", p->data[j]);
    }
    printf("\n");
}

void delect1(sqlist *p) {
    int n;
    n= p->n;
    int s = 0;
    int i;
    if (n == 0) {
        printf("下溢\n");
        return;
    }
    for (i = 0; i<n; i++) {
        if (p->data[i]>=48&&p->data[i]<=57) {
            s++;
        }
        else if (s > 0) {
            p->data[i - s] = p->data[i];
        }
    }
    n -= s;
    printf("\n删除后的表长为:%d",n);
    printf("\n删除后的线性表为: ");
    for (i = 0; i < n; i++) {
        printf("%c ",p->data[i]);
    }
    printf("\n");
}

void delect2(sqlist *p) {
    int n;
    n = p->n;
    int i,j,s;
    char c;
    s = 0;
    if (n == 0) {
        printf("下溢\n");
        return;
    }
    for (i = 0,j=n; i < j; i++) {
        if (p->data[i] >= 48 && p->data[i] <= 57) {
            for (j = n; j > i; j--,n--) {
                if (p->data[j] < 48 && p->data[j] >57) {
                    c = p->data[i];
                    p->data[j] = p->data[i];
                    p->data[j] = c;
                    s++;
                    break;
                }
            }
        }
    }
    n -= s;
    printf("\n删除后的表长为:%d", n);
    printf("\n删除后的线性表为: ");
    for (i = 0; i < n; i++) {
        printf("%c ", p->data[i]);
    }
}

void main() {
    int i;
    sqlist Sqlist;
    init(&Sqlist);
    printf("方法一(一步到位):\n");
    delect1(&Sqlist);
    printf("方法二(交替扫描):\n");
    delect2(&Sqlist);
    gets();
}

猜你喜欢

转载自blog.csdn.net/figurers/article/details/79670813