合肥师范学院数据结构复习资料.docx

上传人:b****4 文档编号:24463550 上传时间:2023-05-27 格式:DOCX 页数:25 大小:23.27KB
下载 相关 举报
合肥师范学院数据结构复习资料.docx_第1页
第1页 / 共25页
合肥师范学院数据结构复习资料.docx_第2页
第2页 / 共25页
合肥师范学院数据结构复习资料.docx_第3页
第3页 / 共25页
合肥师范学院数据结构复习资料.docx_第4页
第4页 / 共25页
合肥师范学院数据结构复习资料.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

合肥师范学院数据结构复习资料.docx

《合肥师范学院数据结构复习资料.docx》由会员分享,可在线阅读,更多相关《合肥师范学院数据结构复习资料.docx(25页珍藏版)》请在冰豆网上搜索。

合肥师范学院数据结构复习资料.docx

合肥师范学院数据结构复习资料

概论

数据是信息的载体,是指能够输入到计算机中,并被计算机识别、存储和处理的符号的集合。

数据元素是数据中具有独立意义的个体。

在有些场合下,也称为元素、记录、结点、定点等。

字段是对元素的详细描述,通常情况下,元素可能包含多个字段。

数据结构是指组成数据的元素之间的结构关系。

逻辑结构(线性、树形、图、集合)

算法是对特定问题求解步骤的一种描述,是指令的有限序列,其中每一条指令表示一个或多个操作。

算法的五个特性:

有穷性、确定性、可行性、输入及输出。

计算时间复杂度:

①for(i=1;i

②for(i=1;i

for(j=1;j<=n;j++){x++;}O(m*n)

③i=1

while(i

线性表

定义:

线性表L是由n个元素a1,a2,…,an组成的有限序列,记做L=(a1,a2,…,an),其中n≥0为表长度;当n=0时L为空表,记做L=()。

特点:

线性表中每个元素最多有一个直接前驱和一个直接后继。

基本运算:

①初始化线性表initial_list(L):

建立线性表的初始结构,即建立空表。

②求表长度list_length(L):

即求表中的元素个数。

③按序号取元素get_element(L,i):

取出表中序号为i的元素。

④按值查询list_locate(L,x):

取出指定值为x的元素,若存在该元素,则返回其地址;否则,返回一个不存在的地址值或标记。

⑤插入元素list_insert(L,i,x):

在表L的第i个元素位置上插入值为x的元素。

⑥删除元素list_selete(L,i):

删除表L中序号为i的元素。

串是由有限个字符a1,a2,a3,…,an组成的序列,记做

S=“a1,a2,a3,…,an”。

串的5个基本算法和2个常用算法:

①赋值运算(S=S1):

将一个串(值)S1传送给串S。

②求长度运算str_length(S):

返回串S的长度值。

③连接运算(S1+S2):

将串S1和S2连接成一个新串。

④求子串函数substr(S,i,j):

返回串S中从第i个元素开始的j个元素所组成的子串。

⑤串比较:

比较两个串的大小。

⑥插入运算str_insert(S,i,S1):

将子串S1插入到串S的从第i个字符开始的位置上。

⑦删除算法str_delete(S,i,j):

删除串S中从第i个字符开始的j个字符。

数组

数组的顺序存储

①以行序为主序的存储(即行优先次序)

②以列序为主序的存储(即列优先次序)

栈是只能在一端进行插入和删除的线性表。

栈具有后进先出或先进后出的特性。

栈的基本算法:

①初始化栈init_stack(S):

设置栈S为空栈。

②判断栈是否为空stack_empty(S):

若栈S为空,返回FALSE。

③取栈顶元素值stack_top(S,x):

若栈S不空,则将栈S的栈顶元素的值送变量x中,否则应返回出错信息。

④入栈push_stack(S,x):

将值为x的元素插入到栈S的栈顶。

若插入前的栈已满,不能入栈时,应报出错信息。

⑤出栈pop_stack(S):

若栈S不空,删除栈S的栈顶元素,否则应返回出错信息。

⑥判断栈是否已满stack_full(S):

栈S满时,返回TRUE;否则,返回FALSE。

队列

队列是只能在一端插入、另一端删除的线性表。

队列的运算

①初始化队列init_queue(Q):

设置队列Q为空。

②判断队列是否为空queue_empty(Q):

若队列Q为空,返回TRUE;否则返回FALSE。

③取队头元素queue_front(Q,x):

若队列Q不空,求出队列Q的队头元素置于x中,否则,返回出错信息。

④入队En_queue(Q,x):

将值为x的元素插入到队列Q中。

若插入前队列已满,不能入队时,应报出错信息。

⑤出队Out_queue(Q,x):

若队列Q不空,删除队头,并将该元素的值置于x中,否则,应返回“下溢出”错误信息。

⑥判断队列是否已满queue_full(Q):

若Q已满,返回TRUE;否则返回FALSE。

树T是n个结点构成的有限集合(n>0),其中有一个结点叫根,其余结点可划分为m个互不相交的子集T1,T2,…,Tm(m≥0),并且这m个子集本身又构成树,称为T的子树。

树的表示形式:

①图形表示法

②嵌套集合表示法

③凹入表表示法

④广义表表示法

树的运算:

①初始化树initial_tree(T):

简历数或森林T的初始结构。

②插入子树insert_tree(T,S):

将以S为根的子树作为T的第一个子树插入到树中。

③插入兄弟结点insert_sibling(T,S):

将以结点S为根的树作为T的兄弟子树插入到树中。

④查询根结点rootof(T):

查询结点T所在树的根结点。

⑤查询父结点fatherof(T):

查询结点T的父结点。

⑥查询孩子结点childof(T):

查询结点T的所有或某个孩子结点。

⑦查询兄弟结点siblingof(T):

查询结点T的所有或某个兄弟结点。

二叉树T是n个结点的有限集合,其中n≥0。

当n=0时,T为空树,否则,其中有一个结点为根结点,其余结点划分为两个互不相交的子集TL、TR,并且TL、TR也构成二叉树,分别称为左右子树。

形态个数计算公式:

1/(n+1)·Cn2n

二叉树的性质:

性质1:

在二叉树的第i层上的结点数≤2i-1(i>0)。

性质2:

深度为k的二叉树的结点数≤2k-1(k>0)。

性质3:

对任意一颗非空的二叉树T如果其叶子数为n0,度为2的结点数为n2,则有关系式n0=n2+1成立。

性质4:

有n个结点的完全二叉树(n>0)的深度为log2n+1.(x表示不大于x的最大整数)

性质5:

在编号的完全二叉树中,各节点的编号之间的关系为:

①如果编号为i的结点存在左孩子结点,则其左孩子结点的编号为2i。

②如果编号为i的结点存在右孩子结点,则其右孩子结点的编号为2i+1。

③如果编号为i的结点存在父结点,则其父结点的编号为i/2。

先序遍历:

先访问根结点,再遍历其左、右子树。

中序遍历:

访问根结点在遍历其左、右子树之间。

后序遍历:

访问根结点在遍历其左、右子树之后。

排序

排序是将数据表调整为按关键字从小到大或从大到小的次序排列的过程。

分类方法:

①增排序和减排序:

②内部排序和外部排序:

数据表中的所有数据是否在内存中。

③稳定排序和不稳定排序:

关键字相同的两个元素的相对次序是否变化。

④排序的基本方法:

插入排序、交换排序、选择排序、归并排序和基数排序。

直接插入排序:

将整个待排序子表看做左右两部分,其中左边为有序区,右边为无序区,整个排序过程就是将右边无序区中的元素逐个插入到左边的有序区中,已构成新的有序区。

稳定;一个存储空间;循环n-1次(①开始有序:

比较和移动元素次数为(n-1)和2(n-1),O(n)。

②逆序:

比较和移动元素次数为(n+2)(n-1)/2和(n+4)(n-1)/2,O(n2))。

希尔排序:

将待排序列划分为若干组,在每组内进行直接插入排序,以使整个序列基本有序,然后再对整个序列进行直接插入排序。

不稳定;各趟O(n),需要log2n趟,总为O(nlog2n)。

冒泡排序:

从一端开始,逐个比较相邻的两个元素,发现倒序即交换。

简单算法O(n2)。

改进算法稳定(①初始正序,比较次数为n-1次,交换0,O(n)。

②初始逆序,第i趟比较与交换均为(n-i),整个比较和交换为n(n-1)/2,O(n2)。

快速排序:

首先,选定一个元素作为中间元素,然后将表中所有元素与该中间元素相比较,将表中比中间元素小的元素调到表的前面,将比中间元素大的元素调到后面,再将中间数放在这两部分之间以作为分界点,这样便得到一个划分。

然后再对左、右两部分分别进行快速排序。

不稳定;时间复杂度(①理想情况下O(nlog2n)。

②另一极端情况下O(n2)。

③一般情况下O(knlog2n),其中k为某常数。

选择排序:

在每一趟排序中,在待排序子表中选出关键字最小或最大的元素放在其最终位置上。

对深度为k的堆,比较至多2(k-1)次,而有n个结点的完全二叉树的深度log2n+1,调整堆比较不超过log2(n-1)+log2(n-2)+…+log22,建初始堆比较不超过4n,O(nlog2n)

查找

查找:

对给定的一个关键字的值,在数据表中搜索出一个关键字的值等于该值的记录或元素。

查找长度:

查找一个元素所进行的关键字的比较次数。

常以平均查找长度、最大查找长度等来衡量查找算法的总的时间性能。

折半查找:

如果查找表A已经按关键字递增(减)有序,此处不妨设为递增数列有序,则可采用二分查找来查找。

二叉排序树是一棵二叉树,或者为空,或者满足如下条件:

①若左子树不空,则左子树上所有结点的值均小于根的值。

②若右子树不空,则右子树上所有结点的值均大于或等于根的值。

③其左、右子树均为二叉排序树。

平衡二叉树是一棵二叉树,或者为空,或者满足如下条件:

①左右子树深度之差的绝对值不超过1。

②左右子树都是平衡二叉树。

结点的平衡因子=结点的左子树深度-结点的右子树深度

平衡化:

LL型调整(①将A的左孩子B提升为新的根结点。

②将原来的根结点A降为新的根结点B的右孩子。

③各子树按照大小关系连接);RR型调整(①将A的右孩子B提升为新的根结点。

②将原来的根结点A降为新的根结点B的左孩子。

③各子树按照大小关系连接。

);LR型调整(①将C提升为新的根结点。

②将原来的根结点A降为新的根结点C的右孩子。

③各子树按照大小关系连接。

);RL型调整(①将C提升为新的根结点。

②将原来的根结点A降为新的根结点C的左孩子。

③各子树按照大小关系连接。

直接插入排序的算法

voidinsert_sort(elementtypeA[n+1])

{

for(i=2;i<=n;i++)

{temp=A[i];

j=i-1;

while(A[j].key>temp.key)

{A[j+1]=A[j];j=j-1;}

A[j+1]=temp;

}

}

带有监视哨的代码

voidinsert_sort(elementtypeA[n+1])

{

for(i=2;i<=n;i++)

{A[0]=A[i];

j=i-1;

while(A[j].key>A[0].key)

{A[j+1]+A[j];j=j-1;}

A[j+1]=A[0];

}

}

设顺序表L是一个递增有序表,试写一个算法,将x插入L中,并使L仍是一个有序表。

voidInsertIncreaseList(Sequenlist*L,Datatypex)

{inti;

for(i=0;ilength&&L->data[i]

InsertList(L,x,i);

}

已知L1和L2分别指向两个单链表的头结点,且已知其长度分别为m和n。

试写一个算法将这两个链表连接在一起。

LinkListLink(LinkListL1,LinkListL2)

{ListNode*p,*q;p=L1;q=L2;

while(p->next)p=p->next;

p->next=q->next;

returnL1;

希尔排序的算法

voidshell_sort(elementtypeA[n+])

{

dh=d1;

while(dh>=1)

{for(i=dh+1;i<=n;i++)

{

temp=A[i];

j=i-dh;

while(j>dh&&A[j].key>temp.key)

{A[j+dh]=A[j];

j=j-dh;

}

A[j+dh]=temp;

}

dh=db/2;

}

}

冒泡排序的算法

voidbubble_sort(elementtypeA[n+1])

{

for(i=1;i

for(j=n;j>=i+1;j--)

if(A[j].key

A[j]<==>A[j-1];

}

改进:

提高时间性能

voidbubble_sort(elementtypeA[n+])

{i=1;

do

{exchanged=FALSE;

for(j=n;j>=i+1;j--)

if(A[j].key

{A[j]<==>A[j-1];exchanged=TRUE;}

i++;

}while(i<=n-1&&exchanged==TRUE);

}

快速排序的算法

划分算法:

voidpartition(elementtypeA[],ints,intt,int&cutpoint)

{x=A[s];

i=s;j=t;

while(i!

=j)

{while(ix.key)j--;

if(i

while(i

if(i

}

A[i]=x;

cutpoint=i;

}

快排算法:

voidQuickSort(elementtypeA[n],ints,intt)

{inti;

if(s

{partition(A,s,t,i);

QuickSort(A,s,i-1);

QuickSort(A,i+1,t);

}

}

选择排序的算法:

直接选择排序

voidselect_sort(elementtypeA[n])

{for(i=0;i

{min=i;

for(j=i+1;j

if(A[j].key

if(min!

=i)A[min]<==>A[i];

}

}

堆排序

堆排序的筛选算法

voidsift(elementtypeA[],intk,intm)

{x=A[k];finished=FALSE;

i=k;j=2*i;

while(j<=m&&!

finished)

{if(j

if(x.key>=A[j].key)finished=TRUE;

else{A[i]=A[j];

i=j;j=2*j;

}

}

A[i]=x;

}

堆排序算法

voidheap_sort(elementtypeA[],intn)

{for(i=n/2;i>=1,i--)

sift(A,i,n);

for(i=n;i>=2;i--)

{A[i]<==>A[1];

sift(A,1,i-1);

}

}

以二叉链表为存储结构,编写一算法交换各结点的左右子树。

Btreeswaptree(btreeb)

{btreet,t1,t2;

if(b==NULL)

t=NULL;

else

{t(btree)malloc(sizeof(btree));

t->data=b->data;

t1=swaptree(b->Lchild);

t2=swaptree(b->Rchild);

t->Lchild=t2;

t->Rchild=T1;

}

return(t);

}

用顺序表将线性表就地逆置

voidReverseList(Seqlist*L)

{Datatypet;

inti;

for(i=0;ilength/2;i++)

{t=L->data[i];

L->data[i]=L->data[L->length-1-i];

L->data[L->length-1-i]=t;

}

}

用单链表将线性表就地逆置

LinkListReverseList(LinkListhead)

{ListNode*p,*q;

if(head->next&&head->next->next)

{p=head->next;q=p->next;p->next=NULL;

while(q)

{p=q;q=q->next;p->next=head->next;

head->next=p;

}

returnhead;

}

returnhead;

}

归并排序的算法

voidmerge(elementtypeA[],elementtypeB[],elementtypeC[],intla,intlb,int&lc)

{intia=1,ib=1,ic=1;

while(ia<=la&&ib<=lb)

if(A[ia]<=B[ib])

C[ic++]=A[ia++];

elseC[ic++]=B[ib++];

while(ia<=la)

C[ic++]=A[ia++];

while(ib<=lb)

C[ic++]=B[ib++];

}

顺序查找算法

intseq_search(elementtypeA[],intn,keytypex)

{i=n;A[0].key=x;

while(A[1].key!

=x)i--;

returni;

}

折半查找的算法

intbin_search(elementtypeA[],intn,keytypex)

{intmid,low=0,high=n-1;

while(low<=high)

{mid=(low+high)/2;

if(x==A[mind].key)returnmid;

elseif(x

elselow=mid+1;

}

return-1;

}

二分查找的递归算法

intbin_search(elementtypeA[],intlow,inthigh,keytypex)

{intmid;

if(low>high)return-1;

else{mid=(low+high)/2;

if(x==A[mid].key)ruturnmid;

elseif(x

returnbin_search(A,low,mid-1,x);

elsereturnbin_search(A,mid+1,high,x);

}

}

二叉排序树的算法

非递归算法

Bnode*bst_search(Bnode*T,keytypex)

{Bnode*P=T;

while(P!

=NULL)

if(x==P->key)returnP;

elseif(xkey)P=P->lchild;

elseP=P->rchild;

returnP;

}

递归算法

Bnode*bst_search(Bnode*T,keytypex)

{if(T==NULL||t->key==x)

returnT;

elseif(xkey)

returnbst_search(T->lchild,x);

elsereturnbst_search(T->rchild,x);

}

二叉排序树中插入结点的实现

voidinsert(Bnode*&T,Bnode*S)

{if(T==NULL)

T=S;

elseif(S->keykey)

insert(T->lchild,S);

elseinsert(T->rchild,S);

}

二叉排序树的构造

voidcreate_bst(Bnode*&T);

{Bnode*u;elementtypex;

T=NULL;cin>>x;

while(x!

=End_of_Num)

{u=newBnode;u->data=x;

u->lchild=NULL;u->rchild=NULL;

insert(T,u);

cin>>x;

}

}

假设在长度大于1的单循环链表中,既无头结点也无指针。

s为指向链表中某个结点的指针,试编写算法删除结点*s的直接前驱结点。

voidDeleteNode(ListNode*s)

{ListNode*p,*q;

p=s;

while(p->next!

=s)

{q=p;p=p->next;}

q->next=s;free(p);

}

输出二叉树T的所有结点的值

voidoutput(BitreeT)

{if(T)

{countleaf(T->child);

cout<data;

countleaf(T->rchild,n);

}

}

求一棵二叉树T的叶子结点数目

voidcountleaf(BitreeT,int&n)

{if(T)

{countleaf(T->child,n);

if(!

T->lchild&&!

T->rchild)n++;

countleaf(T->rchild,n);

}

}

求二叉树的深度

voiddepth(BitreeT)

{if(!

T)return0;

elsereturnmax(high(T->lchild),high(T->rchild))+1;

}

输入一个二叉树的先序序列,构造二叉链表。

voidcreate(Bitree&T)

{cin>>ch;

if(ch=='#')T=NULL;

else{T=newBnode;

T->data=ch;

create(T->lchild);

create(T->rchild);

}

}

先序遍历的非递归算法:

#definemaxsize100

typedefstruct

{BitreeElem[maxsize];

inttop;

}SqStack;

voidPreOrderUnrec(Bitreet)

{SqStacks;

StackInit(s);

p=t;

while(p!

=null||!

StackEmpty(s))

{while(p!

=null)

{visite(p->data);

push(s,p);

p=p->lchild;

}

if(!

StackEmpty(s))

{

p=pop(s);

p=p->rchild;

}

}

}

中序遍历的非递归算法:

#definemaxsize100

typedefstruct

{BitreeElem[maxsize];

inttop;

}SqStack;

voidInOrderUnrec(Bitreet)

{SqStacks;

StackInit(s);

p=t;

while(p!

=null||!

StackEmpty(s))

{while(p!

=null)

{p

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1