资源描述
第一章 绪论
1. 数据结构:主要研究非数值计算问题中计算机得操作对象有哪些结构(逻辑结构)、这些结构在计算机中得表示及其操作得定义与实现问题。
2. 逻辑结构:不考虑实现,仅瞧问题域中数据元素根据相互间得逻辑关系形成得结构称为数据结构得逻辑结构。通常说得数据结构即此义.分类:如书目表根据一对一相邻关系形成线性结构、棋盘格局间根据下棋规则(一对多)形成一个树形数据结构,城市间据通路(多对多)形成图状结构,此外还有集合结构(除同属一个集合外,无其它关联),共四类
3. 数据结构(数据元素及关系/结构)在计算机中得表示或者说映像称为该数据结构得物理结构或存储结构.
4. 顺序存储结构:关系采取顺序映像表示,即借助元素在存储器中得位置上得"相邻"关系隐式表示数据元素间具有关系。此时物理结构对应一个数组。优点:可根据起始地址随机访问各元素。缺点:需事先分配一足够大空间,且插入删除结点需移动大量数据。
链式存储结构:关系采取链式映像表示,即借助附加信息指针显式表示元素间得关系,对应一个链表。优点就是更有效利用空间、插入或者删除结点快,但要顺序访问各元素。
5. 度量指标:算法运行时间主要取决于基本操作得执行次数(频度),执行次数通常随问题规模扩大而增加,增加越快意味着算法随问题规模得扩大,运行时间增长得也快,从而该种算法效果较差;增长越慢算法越好,故可用基本操作得频度随问题规模得增长率反映算法得效率.
6. 时间复杂度:频度函数得增长率基本与函数中“关键项”(去掉低次项与常数项)得增长率相同,故可用“关键项” 反映算法效率。假设关键项为f(n),用T(n)=O(f(n))表示算法时间增长率与f(n)增长率同阶。称O(f(n))为算法得渐近时间复杂度,简称时间复杂度。f(n)得增长率为f(n+1)/f(n),如对复杂度为O(n)得算法其运行时间随问题规模增长率为1+1/n,复杂度为O(1)得算法时间增长率为1.
7. 按增长率由小至大得顺序排列下列各函数 (2/3)n —2100 —㏒2n—n1/2—n -n㏒2n—n3/ 2-2n—n!-nn
第二章 线性表
1. 顺序表:借助元素在存储器中位置上得”相邻”关系表示数据元素间具有得关系,如此存储得线性表称为顺序表。顺序表优点就是实现简单方便,可随机访问各元素;缺点就是插入或删除元素时会引起大量得数据元素移动(表尾除外);对于长度变化较大得线性表,要一次性地分配足够得存储空间,但这些空间常常得不到充分利用。
2. 线性链表:采用链式存储结构得线性表对应一个链表。结点包含数据域与指针域两部分。链表名指向第一个结点 (头指针),尾结点指针域值为NULL。链表优点就是空间利用好,插入删除不移动数据,表头表尾操作快(改进得单链表),位置概念强;缺点就是需要顺序访问各元素,位序概念弱.
顺序表相关程序:
#define LIST_INIT_SIZE 100 //…
#define LISTINCREMENT 10 //…
typedef ***** ElemType;
typedef struct{
ElemType *elem; //存储空间基址
int length; //…
ﻩint listsize; //……
ﻩ}SqList;
SqList La,Lb,Lc;
Status InitList_Sq(SqList &L)
{//构造空线性表L
L、elem=(ElemType*)malloc(LIST_INIT_SIZE
*sizeof(ElemType))
ﻩ if(L、elem==0)ﻩexit(OVERFLOW);
L、length=0; //初始化表长为0,“空”表
ﻩL、listsize=LIST_INIT_SIZE;//初始化存储容量
ﻩ return(OK);
}//InitList_Sq
void ListDelete(SqList &L,int i,ElemType &e)
{//在顺序表L中删除第i个元素,用e返回其值。
//i得合法值就是[1,ListLength(L)]
ﻩif(i<1||i>L、length) return ERROR;//删除位置不合理
ﻩElemType *p=&L、elem[i-1],*q=L、elem+L、length—1;
e=*p;
while(p〈q){*p=*(p+1);++p;}//删除位置后元素左移
ﻩ--L、length;
return Ok;
}//ListDelete_Sq
Status ListInsert_Sq(SqList &L,int i, ElemType e)
{//在顺序表L得第i个位置前插入元素e,i得合法值为1、、L、length+1
if(i<1||i>L、length+1) return ERROR;//插入不合法
ﻩif(L、length>=L、listsize)
{ //表满,增加存储容量
ElemType*newbase=(ElemType *)realloc
(L、elem,(L、listsize+LISTINCREMENT)*sizeof(ElemType))
if(!newbase)ﻩexit(OVERFLOW);
L、elem=newbase;
L、listsize+=LISTINCREMENT;
}
ElemType *q=&L、elem[i-1], *p=&L、elem[L、length—1];
ﻩwhile(p〉=q)
{ *(p+1)=*p; ——p; } //插入位置后得元素右移
*q=e;
ﻩ++L、length;
return OK;
}//ListInsert_S
线性表相关程序:
typedef ***** ElemType;
typedef struct LNode{
ElemType data; //数据域
struct LNode * next; //指针域
}LNode,*LinkList;//默认带头结点,需说明
LNode node1; LinkList La;
Status GetElem_L(LinkList L,int i,ElemType &e)
{//L为带头结点得单链表得头指针.第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
ﻩLNode *p=L->next; //p指向"第1个”结点,
int j=1;ﻩ // j为指向结点得位序
while(p&&j<i)
{ //顺序查找,只要p不空且未到第i结点就前进
ﻩp=p—>next;
++j;
ﻩ}
if(!p)return ERROR; //第i个元素不存在
e=p—>data; //取第i个元素
return OK;
}
Status ListInsert_L(LinkList &L, int i, ElemType e)
{//向链表L中第i个位置插入e
LNode *p=L; int j=0; /*p始终指向第j个结点*/
while(p&&j〈i-1){p=p—〉next; ++j;}//寻找第i-1个结点
ﻩif(!p) return ERROR;
LNode *temp;
temp=(LNode *)Malloc(sizeof(LNode));
if(!temp)ﻩ exit(OVERFLOW);
temp-〉data=e;
temp—>next=p->next;
p->next=temp;
return(OK);
}//ListInsert_L
Status ListDelete_L(LinkList &L, int i, ElemType &e)
{
LNode *p=L,*q; int j=0; /*p始终指向第j个结点*/
while(p&&j〈i—1){p=p-〉next; ++j;}//寻找第i—1个结点,j 最终为i—1,除非到表尾p空
if(!p||!p—>next)
return ERROR;//第i个或更前结点不存在
q=p-〉next;
ﻩe=q-〉data;
p—〉next=q—>next;
free(q);
ﻩreturn(OK);
}//ListDelete_L
Status CreateList_L(LinkList &L, int n)
{//逆位序输入n个元素得值,建立带头结点得单链表L。
LNode *p;
L=(LinkList) malloc(sizeof(LNode));L->next=NULL;
for(int i=1;i<=n;++i)
{
p=(LNode *)malloc(sizeof(LNode));//LNode *等同LinkList
scanf(“…”,&p—>data);
ﻩp-〉next=L-〉next;
L->next=p;//插入到表头
}
}//CreateList_L
相关两表得归并
void MergeList_Sq (SqList La,SqList Lb,Sqlist &Lc)
{//归并非降顺序表La与Lb构成非降顺序表Lc
Lc、listsize=Lc、length=La、length+Lb、length;
Lc、elem=(ElemType*)
malloc(Lc、listsize*sizeof(ElemType));
If(!Lc、elem) exit(OVERFLOW); //存储分配失败
ElemType *pa=La、elem, *pb=Lb、elem, *pc=Lc、elem;
ElemType *pa_last=La、elem+La、listsize—1;
ElemType *pb_last=Lb、elem+La、listsize—1;
while(pa〈=pa_last&&pb<=pb_last)
{//归并
ﻩif(*pa<=*pb)ﻩ*pc++=*pa++;
ﻩelse ﻩ *pc++=*pb++;
}
while(pa<pa_last) *pc++=*pa++; //插入La剩余段
while(pb<pb_last) *pc++=*pb++; //插入Lb剩余段
}//MergeList_Sq
Status ListMerge_SortedL
(SortedSqList La,SortedSqList Lb,SortedSqList &Lc)
{//将两个有序顺序表La与Lb归并为有序顺序表Lc
int la_len=ListLength_Sq(La);
int lb_len=ListLength_Sq(Lb);
ﻩint i=1,j=1,k=1;
ﻩElemType a,b;
ﻩInitList_Sq(Lc);
ﻩwhile(i<=la_len&&j<=lb_len)
{ //归并
GetElem_Sq(La,i,a);GetElem_Sq(Lb,j,b);
ﻩif(a<b) {ListInsert_Sq(Lc,k++,a);++i;}
else{ ListInsert_Sq(Lc, k++,b); ++j;}
}
while(i<=la_len) //插入La得剩余元素
{GetElem_Sq(La,i++,a); ListInsert_Sq(Lc, k++,a);}
while(j〈=lb_len) //插入Lb得剩余元素
ﻩ{GetElem_Sq(Lb,j++,b); ListInsert_Sq(Lc,k++,b);}
return OK;
}//复杂度 O(ListLength(La)+ListLength(Lb),因只在表尾插入)
3. 注意链表中next指针得应用,如插入,删除等操作各个元素得链接。
4. 顺序表得就地逆置思路:分别设两个指针p与q指向第一个与最后一个元素,当p<q时{*p与*q互换,之后++p,—-q}。单链表得就地逆置思路:令指针p指向首元结点,头结点断开,{将p所指结点插入到表头后,p后移,直至p为空}
Status ListInverse_Sq(SqList &L)
{//顺序表就地逆置
ﻩElemType *p,*q;
ElemType e;
ﻩ p=L、elem;q=L、elem+L、length-1;
ﻩ while(p<q)
{
ﻩﻩtemp=*p;ﻩ
*p=*q;
*q=temp;
++p; —-q;
ﻩ}
return OK;
}
Status ListInverse_L(LinkList &L)
{
//思路:令指针p指向首元结点,头结点断开,{将p所指结点插入到表头后,p后移,至p空}
LNode *p,*q;
p=L->next;
L->next=NULL;
while(p!=NULL)
{
q=p-〉next; //令q指向p得后继结点,以便以后p后移接下来两句将p所指向节点插入到头结点后
p—>next=L->next;
L—>next=p;
p=q;//q后移
}
return OK;
}
有序顺序表插入
Status ListInsert_SortedSq(SqList &L,ElemType e)
{//在非降顺序表L中插入元素e,使得L中各元素仍然非降。注意插入位置据e求得
//思路:从最后一个元素开始,只要它比待插入元素大就后移.条件不成立时退出循环,将e插入当前位置后即可。顺序表插入操作莫忘表满得处理。只要就是顺序表得插入操作就需要判断就是否表满,对于链表则无此要求
if(L、length>=L、listsize)
{//表满,增加存储容量
ElemType *newbase=(ElemType *)
realloc(L、elem,(L、listsize+LISTINCREMENT)
*sizeof(ElemType));
ﻩ ﻩif(!newbase) exit(OVERFLOW);
L、elem=newbase; L、listsize+=LISTINCREMENT;
ﻩ}
//下面从最后一个元素开始,只要大于e就后移,最后插入当前位置后
p=L、elem+L、length-1;
while(p〉=L、elem&&*p>e){*(p+1)=*p;-—p;}
*(p+1)=e;
++L、length; //表长加1
return OK;
}
5. 循环链表、双向链表、双向循环链表得特点与基本操作.主要就是插入删除得相关指针操作。
//---线性表得双向(循环)链表存储结构--—
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode,*DuLinkList;
Status ListInsert_DuL(DuLinkList &L,int i,ElemType &e)
{//在带头结点得双向链表L得第i个位置插入e,1≤i≤表长+1
ﻩDuLNode *p=L; int j=0;
while(j〈i—1&&p){p=p—>next;++j;}
ﻩif(!p) return ERROR;
ﻩs=(DuLNode *)malloc(sizeof(DuLNode));
ﻩif(!s)exit(OVERFLOW);
ﻩs—〉data=e;
s-〉prior=p;
s—〉next=p—>next; //记:注意分析指针改变
p—>next-〉prior=s;
p-〉next=s; //次序对结果得影响
ﻩreturn OK;
}
另外瞧下多项式得相关课件,老师复习提纲上有写这方面得代码。
第三章 栈与队列
1. 栈(Stack)就是定义在线性结构上得抽象数据类型,其操作类似线性表操作,但元素得插入、删除与访问都必须在表得一端进行,为形象起见,称允许操作端为栈顶(Top),另一端为栈底(base),注意Top指向待插入位置.特性:Last In First Out后进先出//总就是访问最近插入得一个//按插入顺序倒着访问。
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef ?? SElemType;//栈元素类型
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈容量
ﻩ}SqStack
Status InitStack(SqStack &S)
{//构造空栈S
S、base=(SElemType*)
malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S、base)exit(OVERFLOW); //存储分配失败
ﻩ S、top=S、base; //空栈
S、stacksize=STACK_INIT_SIZE;
ﻩﻩreturn(OK);
}//InitStack 复杂度”O(1)”
Status DestroyStack(SqStack &S)
{//销毁栈S
free(S、base);
S、base=NULL;
S、top=NULL;
S、stacksize=0;
return OK;
} //复杂度O(1)
Status ClearStack(SqStack &S)
{//置S为空栈
S、top=S、base; return OK;
} //复杂度O(1)
Status Push(SqStack &S, SElemType e)
{//插入e为栈顶元素
ﻩif(S、top—S、base==S、stacksize)//判断栈满
{//栈满则应重新分配空间
ﻩS、base=(SElemType *)realloc(S、base,
(S、stacksize+STACKINCREMENT)*sizeof(SElemType));
ﻩif(!S、base)ﻩexit(OVERFLOW);
S、top=(S、base+S、stacksize);//使得S、top重新指向栈顶,因realloc
S、stacksize+=STACKINCREMENT;
}
ﻩ*S、top ++=e; //top指向待插入位置
ﻩreturn(OK);
}//Push ,复杂度O(1)
Status Pop(SqStack &S,SElemType &e)
{//若栈不空则栈顶元素出栈并用e带回其值
if(S、top==S、base) return ERROR;//判断栈空
e=*(—-S、top); //栈顶元素为*(S、top—1)
return OK;
} //复杂度O(1)
Status StackEmpty(SqStack S)
{
if(S、top==S、base)ﻩreturn TRUE;
else ﻩreturn FALSE;
}
int StackLength (SqStack S){ return (S、top—S、base); }
Status GetTop(SqStack S,SElemType &e)
{
if(S、top==S、base) return ERROR;
e=*(S、top-1); //注意top指向待插入位置
return OK;
}
栈得遍历一直没用到,可以自己找找课件瞧。
2. 队列类似线性表与栈,也就是定义在线性结构上得ADT,与线性表与栈得区别在于,元素得插入与删除分别在表得两端进行。类似日常生活中排队,允许插入得一端为队尾(rear),允许删除端称队头(front)。特性:First In First Out先进先出,如操作系统中得作业队列与打印任务队列、日常生活中各类排队业务等均可用队列模拟。
#define *** QElemType
typedef struct QNode {
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct {
QueuePtr front;//队头指针
QueuePtr rear; //队尾指针
} LinkQueue;// 链队列
Status InitQueue (LinkQueue &Q)
{// 构造一个空队列Q
Q、front=Q、rear=(QueuePtr)malloc(sizeof(QNode));
if (!Q、front) ﻩexit (OVERFLOW);
Q、front—〉next = NULL; //莫忘!!
return OK;
}//时间复杂度O(1)
Status DestroyQueue (LinkQueue &Q)
{//销毁队列Q,此处不同于教材,先清空元素结点,后释放头结点
ﻩQueuePtr p=Q、front-〉next;
ﻩwhile(p)
{//依次释放首元素至最后一个元素
Q、front-〉next=p—>next;
free(p);
p=Q、front->next;
}
free(Q、front);
Q、front=NULL;Q、rear=NULL;
return OK;
}//去掉下划线部分为置空操作, 复杂度O(n)
Status EnQueue (LinkQueue &Q, QElemType e)
{// 插入元素e为Q得新得队尾元素
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if (!p)ﻩexit(OVERFLOW);//存储分配失败
p—>data = e; p->next = NULL;//莫忘!!
Q、rear-〉next = p; Q、rear = p;
return OK;
}//复杂度O(1)
Status DeQueue (LinkQueue &Q, QElemType &e)
{// 若队列不空,则删除Q得队头元素,用 e 返回其“值”
if (Q、front ==Q、rear) ﻩreturn ERROR;//空队列
QueuePtr p= Q、front->next; e = p—>data;
Q、front->next = p->next;
if(Q、rear == p) Q、rear=Q、front;//只1个结点时改尾指针
free (p);
return OK;
}//复杂度O(1)
3. 循环队列
#define MAXQSIZE 100 //最大队列长度
typedef struct {
QElemType *base;// 动态分配存储空间
int front; // 头指针,队列不空则指向队列头元素
int rear; // 尾指针, 指向待插入元素位置
} SqQueue;
Status InitQueue (SqQueue &Q)
{// 构造一个空队列Q
Q、base=(QElemType*)malloc(MAXQSIZE*sizeof
(QElemType));
if (!Q、base) exit (OVERFLOW); // 存储分配失败
Q、front = Q、rear = 0;
return OK;
}//复杂度O(1)
Status DestroyQueue(SqQueue &Q)
{// 销毁队列Q
free(Q、base);
Q、front = Q、rear = 0;
return OK;
}//时间复杂度O(1),比链队列快
Status ClearQueue(SqQueue &Q)
{// 将队列Q置空
Q、front=Q、rear=0;//只要想等即可
ﻩreturn OK;
}//复杂度O(1)比链队列快
Status EnQueue (SqQueue &Q, QElemType e)
{// 插入元素e为Q得新得队尾元素,无法插入(已满)则返回ERROR
ﻩif((Q、rear+1)%MAXQSIZE==Q、front)ﻩreturn ERROR;
//判断循环队列满得条件
ﻩQ、base[Q、rear] = e;
ﻩQ、rear = (Q、rear+1) % MAXQSIZE; //加便可能越界,故取余
return OK;
}//时间复杂度O(1)
Status DeQueue (SqQueue &Q, ElemType &e)
{ //队列不空则删除队头元素, 用e带回其值并返OK;否则返ERROR
if (Q、rear==Q、front) return ERROR;//判断循环队列空
e = Q、base[Q、front];
Q、front = (Q、front+1) % MAXQSIZE;
//加就可能越界,故取余
return OK;
} //时间复杂度O(1)
int QueueLength(SqQueue Q)
{ //返回队长
return (Q、rear—Q、front+MAXQSIZE)%MAXQSIZE;
//减可能为负
}//时间复杂度O(1),比链队列快,可修改链队列定义
Status QueueEmpty(SqQueue Q)
{ //判断队列空
if (Q、rear==Q、front) return TRUE;
else return FALSE;
}//O(1)
Status GetHead(SqQueue Q,QElemType &e)
{
if (Q、rear==Q、front) ﻩreturn ERROR;
e=Q、base[Q、front];
return OK;
}// O(1)若要修改对头元素得值可新设SetHead(&Q,e)
4. 证明:若借助栈由输入序列12……n得到得输出序列为p1p2……pn(它就是输入序列得一个排列),则在输出序列中不可能出现这样得情形:存在i<j<k使pj<pk<pi。思路:假设pj<pk<pi往证i<j<k不成立.进一步假设j<k成立,则pj在“pk及pk以后得元素”入栈前已经出栈,故“pk及pk以后得元素”必然后于pj出现,而pi就就是这样得一个元素,其出现次序为i,故i>j,从而i〈j<k不成立。
第四章 串
第五章 数组与广义表
1. 三元组顺序表存储结构:
#define MAXSIZE 12500
typedef struct {
int i, j; //非零元得下标
ElemType e; //非零元得值
} Triple; // 三元组类型
typedef struct{
Triple data[MAXSIZE + 1];//data[0]不用
int mu,nu,tu;//行列数与非零元个数
} TSMatrix; // 稀疏矩阵类型
2. 初始化一个“空"得稀疏矩阵,按照目标矩阵中得出现次序对原矩阵中得元素逐个转置,列号col 从1变到n,每次从头至尾扫描M、data,对列标等于col得三元组,将其行标、列标互换后依次放入T、data[ ]中。
3. 稀疏矩阵得十字链表表示:
typedef Struct{
OLink *rhead,*chead; //行头指针与列头指针数组
int mu, nu, tu
}CrossList
4. 上下三角矩阵存到一位数组得下标转换。相关稀疏矩阵得程序可以瞧瞧课件。
第六章 树与二叉树
1. 树得结构特点:树就是一个层次结构,“有且仅有一个根结点无前驱(第一层);有一或多个叶结点无后继;其余结点有唯一前驱与若干后继”.递归定义:树由根结点(唯一)及该根结点得若干(零或多个)“子树”组成。不含任何结点也就是树,称为空树
2. 树得相关术语如结点,度,见P120。
(1) 结点(node):一个数据元素及其若干指向其子树得分支。
(2) 结点得度(degree) 、树得度:结点所拥有得子树得棵数称为结点得度。树中结点度得最大值称为树得度。
(3) 叶子(left)结点、非叶子结点:树中度为0得结点称为叶子结点(或终端结点)。相对应地,度不为0得结点称为非叶子结点(或非终端结点或分支结点)。除根结点外,分支结点又称为内部结点。
(4) 孩子结点、双亲结点、兄弟结点:一个结点得子树得根称为该结点得孩子结点(child)或子结点;相应地,该结点就是其孩子结点得双亲结点(parent)或父结点。
3. 性质1: 在二叉树得第i层上最多有2i-1个结点(i≥1)
性质2: 深度为K得二叉树最多有2K-1个结点(K≥1)
性质3: 对于任意一棵二叉树BT,如果度为0得结点个数为n0,度为2得结点个数为n2,则n0=n2+1。
证: 二叉树上结点总数 n = n0 + n1 + n2.二叉树上边得总数 e = n1+2n2.根结点外每个结点都有且仅有一条边(分支)"进入”,故e = n-1。由此n-1= n0 + n1 + n2 - 1 ,进而 n0 = n2 + 1 。
性质4:含n个结点得完全二叉树深度为 ëlog2nû +1 。
性质5:若对含 n 个结点得完全二叉树从上到下且从左至右进行 1 至 n 得编号,则对完全二叉树中编号为 i 得结点:
(1) 若 i=1,则该结点就是二叉树得根,无双亲,否则,编号为 ëi/2û 得结点为其双亲结点;
(2) 若 2i〉n,则该结点无左孩子,否则,编号为 2i 得结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子,否则,编号为2i+1 得结点为其右孩子结点.
4. 含n个结点得树中,只有度为k得分支结点与度为0得叶子结点,试求该树含有得叶子结点数
提示:n0+nk=n; e=knk=k(n-n0)=n-1ﻩ故:n0=(nk-n+1)/k
5. 二叉树就是度不大于2得有序树(每个结点最多两棵子树,子树有左右之分)。
6. 满二叉树:设深度为k,含2k-1个结点得二叉树。结点数达最大。
7. 完全二叉树:设树中含n个结点, 它们与满二叉树中编号为1至n得结点位置上一一对应(编号规则为由上到下,从左到右)。相比满二叉树仅少“最后得”若干个,不能少中间得。完全二叉树特点:(1)叶子结点出现在最后2层或多或1层。(2)对于任意结点,若其右分支下得子孙得最大层次为L,则左分支下得子孙得最大层次为L或L+1。
8. 二叉树顺序存储:将二叉树映射到完全二叉树上,不存在得结点以空标记,之后用地址连续得存储单元(一维数组)依次自上而下、自左而右存储完全二叉树上得各元素、(将一般二叉树以完全二叉树形式存储),最坏情况下k个结点需2k—1个单元。但适合完全二叉树得存储,操作简单方便.
9. 二叉树链表存储:二叉链表包含内容,左孩子及右孩子得指针。三叉链表多了一个指向双亲结点得指针。
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree T;
typedef struct TriTNode {
struct TriTNode *parent;
TElemType data;
struct TriTNode *lchild, *rchild;
} TriTNode, *TriTre
10. 先(根)序遍历:树非空则访问根结点,后递归地先序遍历其左子树;再递归地先序遍历其右子树;空则无操作。
中(根)序遍历:树非空则递归地中序遍历根左子树;后访问根结点,再递归地中序遍历右子树;空则无操作.
后(根)序遍历:树非空则递归地后序遍历根右子树;后递归地后序遍历右子树,再访问根结点;空则无操作
层次遍历:由上到下,由左到右,不宜递归
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree T;//
typedef int TElemType;
Status CreateBiTree(BiTree &T)
{//递归创建二叉树
TElemType e; scanf("%d",&e);
if(e==0)ﻩT=NULL;
else
{
ﻩ T=(BiTree)malloc(sizeof(BiTNode));
if(!T)ﻩexit(OVERFLOW);
T->data=e;
CreateBiTree(T->lchild);
ﻩ CreateBiTree(T->rchild);
}
return OK;
}//若元素为字符型则输入时不可随意加空格
Status DestroyBiTree(BiTree &T)
{//二叉链表得后序递归销毁
if(!T) return OK;
else
{
ﻩ DestroyBiTree(T—>lchild
展开阅读全文