1. 在计算机中,算法是指什么?
答案:解题方案的准确而完整的描述。
2. 在下列选项中,哪个不是一个算法一般应该具有的基本特征?
说明:算法的四个基本特征是:可行性、确定性、有穷性和拥有足够的情报(有一个或多个输出、有 零个或多个输入)。
答案:无穷性。
3. 算法一般都可以用哪几种控制结构组合而成?
答案:顺序、选择、循环。
4. 算法的时间复杂度是指?
答案:算法执行过程中所需要的基本运算次数。
5. 算法的空间复杂度是指?
答案:执行过程中所需要的存储空间。
6. 算法分析的目的是?
答案:分析算法的效率以求改进。
7. 下列叙述正确的是(C)
A.算法的执行效率与数据的存储结构无关
B.算法的空间复杂度是指算法程序中指令(或语句)的条数
C.算法的有穷性是指算法必须能在执行有限个步骤之后终止
D.算法的时间复杂度是指执行算法程序所需要的时间
8. 数据结构作为计算机的一门学科,主要研究什么?
答案:主要研究数据的逻辑结构、对各种数据结构进行的运算,以及数据的存储结构。
9. 数据结构中与所使用的计算机无关的是数据的(C)
A.存储结构 B.物理结构
C.逻辑结构 D.物理和存储结构
10. 下列叙述中,错误的是(B)
A.数据的存储结构与数据处理的效率密切相关
B.数据的存储结构与数据处理的效率无关
C.数据的存储结构在计算机中所占的空间不一定是连续的
D.一种数据的逻辑结构可以有多种存储结构
11. 数据的存储结构是指什么?
答案:数据的逻辑结构在计算机中的表示。
12. 数据的逻辑结构是指?
答案:反映数据元素之间逻辑关系的数据结构。
13. 根据数据结构中各数据元素之间前后件关系的复杂程度,一般将数据结构分为?
答案:线性结构和非线性结构。
14. 下列数据结构具有记忆功能的是(C)
A.队列
B.循环队列
C.栈
D.顺序表
15. 下列数据结构中,按先进后出原则组织数据的是(B)
A.线性链表
B.栈
C.循环链表
D.顺序表
16. 递归算法一般需要利用什么实现?
答案:栈
17. 下列关于栈的叙述中正确的是(D)
A.在栈中只能插入数据
B.在栈中只能删除数据
C.栈是先进先出的线性表
D.栈是先进后出的线性表
18. 由两个栈共享一个存储空间的好处是?
答案:节省存储空间,降低上溢发生的机率。
19. 下列关于队列的叙述中正确的是(C)
A.在队列中只能插入数据
B.在队列中只能删除数据
C.队列是先进先出的线性表
D.队列是先进后出的线性表
20. 下列叙述中,正确的是(D)
A.线性链表中的各元素在存储空间中的位置必须是连续的
B.线性链表中的表头元素一定存储在其他元素的前面
C.线性链表中的各元素在存储空间中的位置不一定是连续的,但表头元素一定存储在其他元素的前面
D.线性链表中的各元素在存储空间中的位置不一定是连续的,且各元素的存储顺序也是任意的
21. 下列叙述中正确的是(A)
A.线性表是线性结构
B.栈与队列是非线性结构
C.线性链表是非线性结构
D.二叉树是线性结构
22. 线性表L=(a1,a2,a3,……ai,……an),下列说法正确的是(D)
A.每个元素都有一个直接前件和直接后件
B.线性表中至少要有一个元素
C.表中诸元素的排列顺序必须是由小到大或由大到小
D.除第一个元素和最后一个元素外,其余每个元素都有一个且只有一个直接前件和直接后件
23. 线性表若采用链式存储结构时,要求内存中可用存储单元的地址怎么样?
答案:连续不连续都可以。
24. 链表不具有的特点是(B)
A.不必事先估计存储空间
B.可随机访问任一元素
C.插入删除不需要移动元素
D.所需空间与线性表长度成正比
25. 在(D)中,只要指出表中任何一个结点的位置,就可以从它出发依次访问到表中其他所有结点。
A.线性单链表
B.双向链表
C.线性链表
D.循环链表
26. 以下数据结构属于非线性数据结构的是(C)
A.队列
B.线性表
C.二叉树
D.栈
27. 树是结点的集合,它的根结点数目是多少?
答案:有且只有1。
28. 在一棵二叉树上第8层的结点数最多是?
答案:128
29. 在深度为5的满二叉树中,叶子结点的个数为?
答案:16
30. 在深度为5的满二叉树中,共有多少个结点?
答案:31
31. 设一棵完全二叉树共有699个结点,则在该二叉树中的叶子结点数为?
答案:350
说明:完全二叉树总结点数为N,若N为奇数,则叶子结点数为(N+1)/2;若N为偶数,则叶子结点数为N/2。
32. 设有下列二叉树,对此二叉树中序遍历的结果是(B)
A.ABCDEF
B.DBEAFC
C.ABDECF
D.DEBFCA
33. 若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是?
答案:gdbehfca
34. 串的长度是?
答案:串中所含字符的个数。
35. 设有两个串p和q,求q在p中首次出现位置的运算称做?
答案:模式匹配。
36. N个顶点的连通图中边的条数至少为?
答案:N-1
37. N个顶点的强连通图的边数至少有?
答案:N
38. 对长度为n的线性表进行顺序查找,在最坏情况下所需要的比较次数为?
答案:N
39. 最简单的交换排序方法是?
答案:冒泡排序
40. 假设线性表的长度为n,则在最坏情况下,冒泡排序需要的比较次数为?
答案:n(n-1)/2
41. 在待排序的元素序列基本有序的前提下,效率最高的排序方法是?
答案:冒泡排序
42. 在最坏情况下,下列顺序方法中时间复杂度最小的是?
答案:堆排序
43. 希尔排序法属于?
答案:插入类排序
44. 堆排序法属于?
答案:选择类排序
45. 在下列几种排序方法中,要求内存量最大的是?
答案:归并排序
46. 已知数据表A中每个元素距其最终位置不远,为节省时间,应采用?
答案:直接插入排序
1、反转一个链表。循环算法。
1 List reverse(List l) {
2 if(!l) return l;
3 list cur = l.next;
4 list pre = l;
5 list tmp;
6 pre.next = null;
7 while ( cur ) {
8 tmp = cur;
9 cur = cur.next;
10 tmp.next = pre
11 pre = tmp;
12 }
13 return tmp;
14 }
2、反转一个链表。递归算法。
1 List resverse(list l) {
2 if(!l || !l.next) return l;
3
4 List n = reverse(l.next);
5 l.next.next = l;
6 l.next=null;
7 }
8 return n;
9 }
3、广度优先遍历二叉树。
1 void BST(Tree t) {
2 Queue q = new Queue();
3 q.enque(t);
4 Tree t = q.deque();
5 while(t) {
6 System.out.println(t.value);
7 q.enque(t.left);
8 q.enque(t.right);
9 t = q.deque();
10 }
11 }
----------------------
1class Node {
2 Tree t;
3 Node next;
4 }
5class Queue {
6 Node head;
7 Node tail;
8 public void enque(Tree t){
9 Node n = new Node();
10 n.t = t;
11 if(!tail){
12 tail = head = n;
13 } else {
14 tail.next = n;
15 tail = n;
16 }
17 }
18 public Tree deque() {
19 if (!head) {
20 return null;
21 } else {
22 Node n = head;
23 head = head.next;
24 return n.t;
25 }
26}
4、输出一个字符串所有排列。注意有重复字符。
1char[] p;
2void perm(char s[], int i, int n){
3 int j;
4 char temp;
5 for(j=0;j<n;++j){
6 if(j!=0 && s[j]==s[j-1]);
7 elseif(s[j]!='@'){
8 p[i]=s[j];
9 s[j]='@';
10 if(i==n-1){
11 p[n]='\0';
12 printf("%s", p);
13 }else{
14 perm(s,i+1,n);
15 }
16 s[j]=p[i];
17 }
18 }
19}
--------------------------
1void main() {
2 char s[N];
3 sort(s);
4 perm(s,0,strlen(s));
5}
5、输入一个字符串,输出长型整数。
1 long atol(char *str){
2 char *p = str;
3 long l=1;m=0;
4 if (*p=='-') {
5 l=-1;
6 ++p;
7 }
8 while(isDigit(*p)){
9 m = m*10 + p;
10 ++p;
11 }
12 if(!p) return m*l;
13 else return error;
14}
6、判断一个链表是否有循环。
1 int isLoop(List l) {
2 if ( ! l) return - 1 ;
3 List s = l.next;
4 while (s && s != l) {
5 s = s.next;
6 }
7 if ( ! s) return - 1 ;
8 else reutrn 1 ;
9 }
-----------
1int isLoop(List l){
2 if(!l) return 0;
3 p=l.next;
4 wihle(p!=l&&p!=null) {
5 l.next=l;
6 l=p;p=p.next;
7 }
8 if(p=l) return 1;
9 return 0;
10}
实际上,在我的面试过程中,还问到了不破坏结构的其他算法。
我的答案是从链表头开始遍历,如果节点next指针指向自身,则循环存在;否则将next指针指向自身,遍历下一个节点。直至next指针为空,此时链表无循环。
7、反转一个字符串。
1 void reverse( char * str) {
2 char tmp;
3 int len;
4 len = strlen(str);
5 for ( int i = 0 ;i < len / 2 ; ++ i) {
6 tmp = char [i];
7 str[i] = str[len - i - 1 ];
8 str[len - i - 1 ] = tmp;
9 }
10 }
8、实现strstr函数。
1int strstr(char[] str, char[] par){
2 int i=0;
3 int j=0;
4 while(str[i] && str[j]){
5 if(str[i]==par[j]){
6 ++i;
7 ++j;
8 }else{
9 i=i-j+1;
10 j=0;
11 }
12 }
13 if(!str[j]) return i-strlen(par);
14 else return -1;
15}
9、实现strcmp函数。
1int strcmp(char* str1, char* str2){
2 while(*str1 && *str2 && *str1==*str2){
3 ++str1;
4 ++str2;
5 }
6 return *str1-*str2;
7}
10、求一个整形中1的位数。
1 int f( int x) {
2 int n = 0 ;
3 while (x) {
4 ++ n;
5 x &= x - 1 ;
6 }
7 return n;
8 }
11、汉诺塔问题。
1void tower(n,x,y,z){
2 if(n==1) move(x,z);
3 else {
4 tower(n-1, x,z,y);
5 move(x,z);
6 tower(n-1, y,x,z);
7 }
8}
12、三柱汉诺塔最小步数。
1 int f3(n) {
2 if (f3[n]) return f3[n];
3 else {
4 if (n == 1 ) {
5 f3[n] = 1 ;
6 return 1 ;
7 }
8 f3[n] = 2 * f3(n - 1 ) + 1 ;
9 return f3[n];
10 }
11 }
四柱汉诺塔最小步数。
1int f4(n){
2 if(f4[n]==0){
3 if(n==1) {
4 f4[1]==1;
5 return 1;
6 }
7 min=2*f4(1)+f3(n-1);
8 for(int i=2;i<n;++i){
9 u=2*f4(i)+f3(n-i);
10 if(u<min) min=u;
11 }
12 f4[n]=min;
13 return min;
14 } else return f4[n];
15}
13、在一个链表中删除另一个链表中的元素。
1void delete(List m, List n) {
2 if(!m || !n) return;
3 List pre = new List();
4 pre.next=m;
5 List a=m, b=n,head=pre;
6 while(a && b){
7 if(a.value < b.value) {
8 a=a.next;
9 pre=pre.next;
10 }else if(a.value > b.value){
11 b=b.next;
12 }else{
13 a=a.next;
14 pre.next=a;
15 }
16 }
17 m=head.next;
18}
14、一个数组,下标从0到n,元素为从0到n的整数。判断其中是否有重复元素。
1int hasDuplicate(int[] a, int n){
2 for(int i=0;i<n;++i){
3 while(a[i]!=i && a[i]!=-1){
4 if(a[a[i]]==-1) return 1;
5 a[i]=a[a[i]];
6 a[a[i]]=-1;
7 }
8 if(a[i]==i) {a[i]=-1;}
9 }
10 return 0;
11}
15、判断一颗二叉树是否平衡。
1int isB(Tree t){
2 if(!t) return 0;
3 int left=isB(t.left);
4 int right=isB(t.right);
5 if( left >=0 && right >=0 && left - right <= 1 || left -right >=-1)
6 return (left<right)? (right +1) : (left + 1);
7 else return -1;
8}
9
16、返回一颗二叉树的深度。
1int depth(Tree t){
2 if(!t) return 0;
3 else {
4 int a=depth(t.right);
5 int b=depth(t.left);
6 return (a>b)?(a+1):(b+1);
7 }
8}
17、两个链表,一升一降。合并为一个升序链表。
1 List merge(List a, List d) {
2 List a1 = reverse(d);
3 List p = q = new List();
4 while ( a && a1 ) {
5 if (a.value < a1.value) {
6 p.next = a;
7 a = a.next;
8 } else {
9 p.next = a1;
10 a1 = a1.next;
11 }
12 p = p.next;
13 }
14 if (a) p.next = a;
15 elseif(a1) p.next = a1;
16 return q.next;
17 }
18、将长型转换为字符串。
1char* ltoa(long l){
2 char[N] str;
3 int i=1,n=1;
4 while(!(l/i<10)){i*=10;++n}
5 char* str=(char*)malloc(n*sizeof(char));
6 int j=0;
7 while(l){
8 str[j++]=l/i;
9 l=l%i;
10 i/=10;
11 }
12 return str;
13}
19、用一个数据结构实现
1 if (x == 0) y = a;
2 else y = b;
1 j[] = {a,b};
2 y=j[x];
20、在双向链表中删除指定元素。
1void del(List head, List node){
2 List pre=new List();
3 pre.next = head;
4 List cur = head;
5 while(cur && cur!=node){
6 cur=cur.next;
7 pre=pre.next;
8 }
9 if(!cur) return;
10 List post = cur.next;
11 pre.next=cur.next;
12 post.last=cur.last;
13 return;
14}
21、不重复地输出升序数组中的元素。
1 void outputUnique( char [] str, int n) {
2 if (n <= 0 ) return ;
3 elseif(n == 1 ) putchar(str[ 0 ]);
4 else {
5 int i = 0 ,j = 1 ;
6 putchar(str[ 0 ]);
7 while (j < n) {
8 if (str[j] !== str[i]) {
9 putchar(str[j]);
10 i = j;
11 }
12 ++ j;
13 }
14 }
15 }
22、面试过程中我还遇到了下面几题:
1、如何删除链表的倒数第m的元素?我的方法是先用pre指针从链表头开始步进m,新建pst节点next指针指向头节点,cur指针指向头节点,然后pre,cur,post三个指针一起步进,当pre指向链表结尾的时候cur指向倒数第m个元素,最后利用pst指针删除cur指向元素。
2、如何判断一个字符串是对称的?如a,aa,aba。设置头尾指针同时向中间比较靠齐直至相遇。
3、如何利用2函数找出一个字符串中的所有对称子串?以子串头指针和尾指针为循环变量设置两个嵌套的循环以找出所有子串,对每个子串应用2函数。