收藏 分享(赏)

Data Stuctures And Algorthms a.doc

上传人:hwpkd79526 文档编号:9068264 上传时间:2019-07-22 格式:DOC 页数:35 大小:122KB
下载 相关 举报
Data Stuctures And Algorthms a.doc_第1页
第1页 / 共35页
Data Stuctures And Algorthms a.doc_第2页
第2页 / 共35页
Data Stuctures And Algorthms a.doc_第3页
第3页 / 共35页
Data Stuctures And Algorthms a.doc_第4页
第4页 / 共35页
Data Stuctures And Algorthms a.doc_第5页
第5页 / 共35页
点击查看更多>>
资源描述

1、数据结构 知识:1.数据结构中对象的定义,存储的表示及操作的实现.2.线性:线性表、栈、队列、数组、字符串(广义表不考)树:二叉树集合:查找,排序图(不考 )能力:分析,解决问题的能力过程: 确定问题的数据。 确定数据间的关系。 确定存储结构(顺序数组、链表指针) 确定算法 编程 算法评价(时间和空间复杂度,主要考时间复杂度)一、数组1、存放于一个连续的空间2、一维多维数组的地址计算方式已知 data00的内存地址,且已知一个元素所占内存空间求 dataij在内存中的地址。公式:(add+(i*12+j)*S)(假设此数组为 data1012)注意:起始地址不是 data00时候的情况。起始地

2、址为 data-38和情况;3、顺序表的定义存储表示及相关操作4、顺序表操作中时间复杂度估计5、字符串的定义(字符串就是线性表),存储表示模式匹配算法(简单和 KMP(不考)6、特殊矩阵:存储方法(压缩存储(按行,按列)三对角:存储于一维数组三对角问题:已知 Aij 能求出在一维数组中的下标 k;已知下标 k 求 Aij。7、稀疏矩阵:定义,存储方式:三元组表、十字链表(属于图部分,不考) 算法 数组中元素的原地逆置; 对换 在顺序表中搜索值为 X 的元素; 在有序表中搜索值为 X 的元素;(折半查找) 在顺序表中的第 i 个位置插入元素 X; 在顺序表中的第 i 个位置删除元素 X; 两个有

3、序表的合并;算法?线性表数据结构定义:Typedef struct int datamax_size;int len;linear_list; 模式匹配 字符串相加 求子串 (i,j)K 注意:不同矩阵所用的公式不同; 稀疏矩阵的转置(两种方式,后种为妙) 和数组有关的算法 例程:求两个长整数之和。a=13056952168b=87081299数组:a:1 3 0 5 6 9 5 2 1 6 8b:8 7 0 8 1 2 9 9 由于以上的结构不够直观(一般越是直观越容易解决 ) 将其改为:a:11 8 6 1 2 5 9 6 5 0 3 1 a0=11(位数)b: 8 9 9 2 1 8 0

4、 7 8 0 0 0 b0=8c 进位 0 1 1 0 0 1 1 1 1 0 0 c:11 7 6 4 3 3 0 4 4 2 3 1 c0的值(C 位数)由 cmax_s+1决定!注意: 在求 C 前应该将 C(max_s+1)位赋 0.否则为随机数 ; 较小的整数高位赋 0.算法: 已知 a,b 两个长整数,结果:c=a+b;总共相加次数: max_s=max(a,b)程序:for(i=1;i#include#define PRIN printf(“n“);int flag=0; /*a0b0?1:0*/* max(a,b) */change(char da,char db,int a,

5、int b,int c) int i;if(a0b0) for(i=1;i=1;i-)printf(“%d,“,mi); PRINmain()int s;int a20,b20,c20;char da=“123456789“;char db=“12344443“;a0=strlen(da);b0=strlen(db);printf(“a0=%dt“,a0);printf(“b0=%d“,b0); PRINchange(da,db,a,b,c);printf(“flag=%dn“,flag); PRINprintf(“-n“);if(flag=1) print(a); PRINs=abs(a0-

6、b0);printf(“+“);for(s=s*2-1;s0;s-)printf(“ “);print(b); PRINelse s=abs(a0-b0);printf(“+“);for(s=s*2-1;s0;s-)printf(“ “);print(a); PRINprint(b); PRINadd(a,b,c);printf(“-n“);print(c);时间复杂度计算: 确定基本操作 计算基本操作次数 选择 T(n) lim(F(n)/T(n)=c 0(T(n)为时间复杂度上例子的时间复杂度为 O(max_s); 二:链表1、知识点逻辑次序与物理次序不一致存储方法;单链表的定义:术语(头

7、结点、头指针等)注意带头结点的单链表与不带头结点的单链表区别。(程序员考试一般不考带头结点,因为稍难理解)插入、删除、遍历( p=NULL 表明操作完成)等操作 循环链表:定义,存储表示,操作; 双向链表:定义,存储方法,操作;单链表和循环链表区别在最后一个指针域值不同。2、操作单链表:插入 X,删除 X,查找 X,计算结点个数单链表的逆置(中程曾考)head-NULL/p-a1/p-a2/p-a3/pan/NULL 注:p 代表指针;NULL/p 代表头结点 head-NULL/p-an/p-an-1/p-an-2/pa1/NULL 循环链表的操作:插入 X,删除 X,查找 X,计算结点个数

8、;用 p=head-next 来判断一次计算结点个数完成;程序段如下:k=0;dok+;p=p-next;while(p!=head-next); 双向链表多项式相加 有序链表合并 例程:已知两个字符串 S,T ,求 S 和 T 的最长公子串;1、逻辑结构:字符串2、存储结构:数组3、算法: 精化(精细化工)*老顽童注:此处“精细化工”说明好像不对!s=“abaabcacb“ t=“abdcabcaabcda“当循环到 s.len-1 时,有两种情况:s=“abaabcacb“、 s=“abaabcacb“ s.len-2 时,有三种情况:s=“abaabcacb“、 s=“abaabcacb

9、“、s=“abaabcacb“ .1 s.len 种情况程序思路:tag=0 /没有找到for(l=s.len;l0l-) 判断长度为 l 的 s 中的子串是否为 t 的子串;若是:tag=1;长度为 l 的 s 的子串在 s 中有(s.len-l+1)个。子串 0: 0l-11: 1l 2: 2l+1 3: 3l+2 s.len-l: s.len-ls.len-1由上面可得:第 j 个子串为 jl+j-1。判断长度为 l 的 s 中的子串是否为 t 的子串:for(j=0;j0l-) for(j=0;j5!=4!=3!=2!=1!=0!2) 回归 720后缀5) 迷宫问题6) 线性链表的递归

10、算法 一个链表= 一个结点+ 一个链表int fuction(NODE *p) if(p=NULL) return 0;else return(function(p-next);树与二叉树一、 知识点:1. 树的定义 : data_struct(D,R);其中:D 中有一个根,把 D 和出度去掉,可以分成 M 个部分 .D1,D2,D3,D4,D5DMR1,R2,R3,R4,R5RM而子树 Ri 形成树.1) 递归定义 高度2) 结点个数=1 O -0O O -1O O O O -2此树的高度为 22.二叉树定义 : 结点个数=0 .3. 术语:左右孩子,双亲, 子树, 度,高度等概念.4.

11、二叉树的性质层次为 I 的二叉树 I 层结点 2I 个高度为 H 的二叉树结点 2H+1-1 个H(点)=E( 边)+1个数为 N 的完全二叉树高度为|_LOG 2n_|完全二叉树结点编号 :从上到下,从左到右. i 结点的双亲: |_i/2_| |_i-1/2_| 1i 结点的左孩子: 2i 2i+1 2 3i 结点的右孩子: 2i+1 2i+2 4 5 6 7(根) 1 为起点 0 为起点二叉树的存储结构:1) 扩展成为完全二叉树, 以一维数组存储。 AB CD EFGHI数组下标0 123456789101112元素 ABCDEFGH I2) 双亲表示法 数组下标 0 1 2 3 4 5

12、 6 7 8元素 A B C D E F G H I双亲 -1 0 0 1 2 2 3 3 43) 双亲孩子表示法 数组下标 0 1 2 3 4 5 元素 A B C D E F 双亲 -1 0 0 1 2 2 左子 1 3 4 右子 2 -1 5 结构:typedef struct datatype data;int parent;int lchild;int rchild;NODE;NODE treeN; / 生成 N 个结点的树4) 二叉链表5) 三叉链表6) 哈夫曼树5.二叉树的遍历先根 中根 栈 中根遍历(左子树 )根(右子树),再用相同的方法处理左子树, 右子树.后根 /先,中序已

13、知求树:先序找根 ,中序找确定左右子树.层次遍历(队列实现)6.线索二叉树 (穿线树)中序线索二树树目的:利用空指针直接得到中序遍历的结果.手段(方法 ):左指针为空, 指向前趋,右指针为空,指向后继.结点结构: ltag Lch Data rch rtagLtag=0,lch 指向左孩子,ltag=1,指向前趋结点Rtag=0,rch 指向右孩子;rtag=1,指向后继结点中序遍历: 1) 找最左结点(其左指针为空)2) 当该结点的 rtag=1,该结点的 rch 指向的就为后继3) 当 rtag=0,后继元素为右子树中最左边那个N 个结点的二树有空指针 N+1 个 周六我去了周 SIR 的

14、办公室,他很热情,我问的是中序线索化二叉树的问题( 递归),关于这个问题我会在以后的笔记中作重点补充。我在这学校从来没有碰到过像他这样热情的老师,真的,大一的时候我们学校就开了 C,当时我就连#include这句话的意思都不晓得,别说是让我写程序了(到这份上也不怕把丑事都抖出来了:数据结构的课程设计也是哈科大的 littlebob 兄帮我做的,很遗憾,他高程就差几分,希望他早日成功,我们都要向他学习)等于说我的 C 知识九成都是在大二下学期的时候学的。而且全是自学的。拿这个周末来说吧。我三天时间就看完了一本 C 语言大全。当然,并不是从头到尾,只是根据自己的实际情况,重点是指针和数据结构那块。

15、C 最要的便是指针。程序员考试下午试题最重要的便是递归问题(12 道,没有掌握就没希望了哦)。我说这些并不是为了表明自己多么用功,只是希望每位“学者“ 都有所侧重。查找 一、 知识点 /静态查找-数组 1、 什么是查找动态查找-链树顺序查找,时间复杂度 O(n)折半查找:条件:有序;时间复杂度 O(nlog2n) (时间复杂度实际上是查找树的高度)索引查找:条件:第 I+1 块的所有元素都大于第块的所有元素。算法:根据 index 来确定 X 所在的块(i) 时间复杂度:m/2 在第块里顺序查找 X 时间复杂度:n/2 总的时间复杂度:(m+n)/2二叉排序树 1 )定义:左子树键值大于根节点

16、键值;右子树键值小于根的键值,其左右子树均为二叉排序树。 2)特点:中序遍历有序- (删除节点用到此性质)3)二叉排序树的查找:如果根大于要查找的树,则前左子树前进,如果根小于要查找的树,则向右子树前进。4)结点的插入- 二叉排序树的构造方法5)结点删除(难点) 1、右子树放在左子树的最右边2、左子树放在右子树的最左边avl 树(二叉平衡树):左右子树高度只能差层,即h 13 16 11 18 21 3 17 6 24 8 d2i+1while(id2*i+2) 8 24 did2*i+1; 24 21 - 8 21i=2*i+1;else did2*i+2;i=2*i+2;elseflag=

17、1; /是堆堆排序过程:基数排序 (多关键字排序)扑克: 1) 大小-分配2) 花色-分配,收集思想: 分配再收集 .构建链表:链表个数根据关键字取值个数有关.例: 将下面九个三位数排序:321 214 665 102 874 699 210 333 600定义一个有十个元素的数组:a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 第一趟(个位): 210 321 102 333 214 665 699 600 874结果: 210 600 321 102 333 214 874 665 699第二趟(十位): 600 210 321 333 665 874 699 102 214

18、结果: 600 102 210 214 321 333 665 874 699第三趟(百位): 102 210 321 600 874214 333 665699结果: 102 210 214 321 333 600 665 699 874(排序成功)最近在看一位程序员的笔记,也挺不错的啊.这应当是他的网站.他总说他的网站人气不够,现在顺便就帮他宣传一下啦!http:/ 程序员考试下午试题最后一道一般是八大类算法里头的.大家尤其要注意的是递归,因为近几年都考了,而且有的还考两题。可以说如果我们不掌握递归就没有掌握 C,况且递归是 C 里的难点。为了控制合格率,程序员考试不会让我们轻松过关的,为

19、了中国软件业,我想也应该这样啊。/数据结构(离散)迭代数值计算(连续)枚举 策略好坏很重要递推递归回溯分治贪婪动态规划其中:递推、递归、分治、动态规划四种算法思想基本相似。都是把大问题变成小问题,但技术上有差别枚举:背包问题:枚举策略:1)可能的方案:2 N2)对每一方案进行判断.枚举法一般流程:while(还有其他可能方案) 按某种顺序可难方案;检验方案;if(方案为解)保存方案;枚举策略:例:把所有排列枚举出来 P6=6!.Min:123456Max:654321a1a2a3a4a5a6=?(下一排列)=?比如:312654 的下和种情况=314256递归递归算法通常具有这样的特征:为求解

20、规模为 N 的问题,设法将它分解成一些规模较小的问题,然后从这些较小问题的解能方便地构造出题目所需的解。而这些规模较小的问题也采用同样的方法分解成规模更小的问题,通过规模更小的问题构造出规模校小的问题的解,如此不断的反复分解和综合,总能分解到最简单的能直接得到解的情况。因此,在解递归算法的题目时,要注意以下几点:1) 找到递归调用的结束条件或继续递归调用条件.2) 想方设法将处理对象的规模缩小或元素减少.3) 由于递归调用可理解为并列同名函数的多次调用,而函数调用的原则是一层一层调用,一层一层返回.因此,还要注意理解调用返回后的下一个语句的作用. 在一些简单的递归算法中,往往不需要考虑递调用返

21、回后的语句处理.而在一些复杂的递归算法中,则需要考虑递归调用返回后的语句处理和进一步的递归调用.4) 在读递归程序或编写递归程序时, 必须要牢记递归函数的作用, 这样便于理解整个函数的功能和知道哪儿需要写上递归调用语句.当然,在解递归算法的题目时,也需要分清递归函数中的内部变量和外部变量.表现形式:定义是递归的 (二叉树,二叉排序树)存储结构是递归的 (二叉树,链表,数组)由前两种形式得出的算法是递归的一般流程: function(variable list(规模为 N) if(规模小,解已知) return 解;else 把问题分成若干个部分;某些部分可直接得到解;而另一部分(规模为 N-1

22、)的解递归得到;例 1:求一个链表里的最大元素.大家有没想过这个问题用递归来做呢?非递归方法大家应该都会哦?Max(nodetype *h) nodetype *p;nodetype *q; /存放含最大值的结点Int max=0;P=h;While(p!=NULL)if (maxdata) max=p-data;q=p;p=p-next;return q;下面真经来了,嘻嘻嘻*max(nodetype *h) nodetype *temp;temp=max(h-next);if(h-datatemp-data)return h;elsereturn temp;大家有空想想下面这个算法:求链表

23、所有数据的平均值(我也没试过) ,不许偷懒,用递归试试哦!递归程序员考试题目类型:1)就是链表的某些操作( 比如上面的求平均值)2)二叉树( 遍历等)例 2.判断数组元素是否递增int jidge(int a,int n) if(n=1) return 1;elseif(a0a1) return 0;else return jidge(a+1,n-1);例 3.求二叉树的高度 (根据二叉树的递归性质:(左子树) 根(右子树)int depth(nodetype *root) if(root=NULL) return 0;else h1=depth(root-lch);h2=depth(root

24、-rch);return max(h1,h2)+1;自己想想求二叉树结点个数(与上例类似)例 4.已知中序遍历和后序遍历,求二叉树.设一二叉树的:中序 S:E D F B A G J H C Istart1 j end1后序 T:E F D B J H G I C Astart2 end2node *create(char *s,char *t, int start1,int start2,int end1,int end2) if (start1end1) return NULL; /回归条件root=(node *)malloc(sizeof(node);root-data=tend2;找

25、到 S 中 Tend2的位置为 jroot-lch=create(S,T,s1,j-1,start1,j+start2-start1-1);root-rch=create(S,T,j+1,end1,j+start2-start1,end2-1);return root;例 5.组合问题n 个数: (1,2,3,4,n)求从中取 r 个数的所有组合.设 n=5,r=3;递归思想:先固定一位 5 (从另四个数当中选二个)5,4 (从另三个数当中选一个)5,4,3 (从另二个数当中选零个)即:n-2 个数中取 r-2 个数的所有组合程序:void combire(int n,int r) for(k

26、=n;k=n+r-1;k-) ar=k;if(r=0) 打印 a 数组(表示找到一个解);else combire(n-1,r-1);回溯法:回溯跟递归都是程序员考试里常出现的问题,大家必须掌握 !回溯法的有关概念:1) 解答树:叶子结点可能是解,对结点进行后序遍历.2) 搜索与回溯五个数中任选三个的解答树(解肯定有三层,至叶子结点): ROOT 虚根/ / | 1 2 3 4 5/ | | / | / |2 3 4 5 3 4 5 4 5 5/| / | / | |3 4 5 4 5 5 4 5 5 5回溯算法实现中的技巧:栈要搞清回溯算法,先举一个(中序遍历二叉树的非递归算法 )来说明栈在

27、非递归中所起的作用。A 过程:push()-push()-push()-push()栈内结果:ABDE(E 为叶子, 结束进栈)/ pop() ABD(E 无右孩子,出栈)B C pop() AB(D 无右孩子,出栈) / pop() A(B 有右孩子,右孩子进栈)D F . ./ / . .E G H . ./ . .I 最后结果: EDBGFIHAC简单算法:if(r!=NULL) /树不空 while(r!=NULL) push(s,r);r=r-lch; /一直向左孩子前进while(!empty(s) / 栈非空,出栈 p=pop(s);printf(p-data);p=p-rch;

28、 /向右孩子前进while(p!=NULL) push(s,p);p=p-lch; /右孩子进栈 / 这就是传说中的回溯,嘻嘻没吓着你吧5 选 3 问题算法:思想: 进栈 :搜索出栈: 回溯边建树(进栈 )边遍历(出栈)基本流程: 太复杂了,再说我不太喜欢用 WORD 画图(有损形象),以后再整理!程序: n=5;r=3init(s) /初始化栈push(s,1) /根进栈while(s.topr-1) /孩子入栈while(!empty(s) if(s.top=r-1)判断该“解“ 是否为解 .x=pop(s); /保留 x,判断是否为最大值 n,如果是 n,则出栈while(x=n)x=pop(s);push(s,x+1);while(s.topr-1)背包问题: TW=20 , w5=6,10,7,5,8 解的条件:1) 该解答树的叶子结点2) 重量最大

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报