一些数据结构的题目

1. 在二叉搜索树中找出和为某一值的所有路径并从根节点打印。

    例如输入整数22 和如下二叉搜索树,则打印出两条路径:10, 12 和10, 5, 7。
    10
    /  \
   5   12
  / \
 4   7

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 #define max_length 100
 6 struct TreeNode {
 7   int data;
 8   TreeNode * left;
 9   TreeNode * right;
10 };
11 
12 void printPaths(TreeNode * root, int sum);
13 void printPath(int path[], int size);
14 void helper(TreeNode * root, int sum, int path[], int top);
15 void printTree(TreeNode *root);
16 
17 
18 int main(){
19     TreeNode root, five, four, seven, twelve;
20     root.data = 10;
21     five.data = 5;
22     four.data = 4;
23     seven.data = 7;
24     twelve.data = 12;
25 
26     root.left = &five;
27     root.right = &twelve;
28     five.left = &four;
29     five.right = &seven;
30 
31     four.left = NULL;
32     four.right = NULL;
33 
34     seven.left = NULL;
35     seven.right = NULL;
36 
37     twelve.left = NULL;
38     twelve.right = NULL;
39 
40     printPaths(&root, 22);
41     //printTree(&root);
42     return 0;
43 }
44 
45 
46 
47 void printPaths(TreeNode * root, int sum) {
48   int path[max_length];
49   helper(root, sum, path, 0);
50 }
51 
52 void printPath(int path[], int size){
53     for(int i=0;i<size;i++){
54         cout << path[i] << " ";
55     }
56     cout << endl;
57 }
58 
59 void helper(TreeNode * root, int sum, int path[], int top) {
60     if(sum - root->data < 0){
61         return;
62     }
63     path[top++] = root->data;
64     sum -= root->data;
65 
66     if (root->left == NULL && root->right==NULL) {
67         if (sum == 0)
68             printPath(path, top);
69     } else {
70     if (root->left != NULL)
71         helper(root->left, sum, path, top);
72     if (root->right!=NULL)
73         helper(root->right, sum, path, top);
74   }
75 }
76 
77 void printTree(TreeNode *root){
78     if(root != NULL){
79         cout << root->data << endl;
80 
81         if(root->left != NULL){
82             printTree(root->left);
83         }
84 
85         if(root->right != NULL){
86             printTree(root->right);
87         }
88     }
89 }

 

 

2. 求子数组的最大和,要求时间复杂度为O(n)。例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2。

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 
 6 int maxSubarray(int a[], int size);
 7 int main(){
 8     int arr[] = {1, -2, 3, 10, -5, 6};
 9     int maxSub = maxSubarray(arr, 6);
10     cout << maxSub << endl;
11 
12     return 0;
13 }
14 
15 int maxSubarray(int a[], int size) {
16   if (size<=0)
17       return 0;
18   int sum = 0;
19   int max = - (1 << 31);
20   int cur = 0;
21   while (cur < size) {
22     sum += a[cur++];
23     if (sum > max) {
24       max = sum;
25     } else if (sum < 0) {
26       sum = 0;
27     }
28   }
29   return max;
30 }

 

 

3. 设计包含min 函数的栈。定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。要求函数min、push 以及pop 的时间复杂度都是O(1)。

    tips:栈区别于队列,在栈弹出元素之后,剩下的元素是该元素进入栈之前的元素。因此不影响之前的结构。但是队列就会影响。

 1 struct MinStackElement {
 2   int data;
 3   int min;
 4 };
 5 
 6 struct MinStack {
 7   MinStackElement * data;
 8   int size;
 9   int top;
10 }
11 
12 MinStack MinStackInit(int maxSize) {
13   MinStack stack;
14   stack.size = maxSize;
15   stack.data = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize);
16   stack.top = 0;
17   return stack;
18 }
19 void MinStackFree(MinStack stack) {
20   free(stack.data);
21 }
22 void MinStackPush(MinStack stack, int d) {
23   if (stack.top == stack.size) error(“out of stack space.”);
24   MinStackElement* p = stack.data[stack.top];
25   p->data = d;
26   p->min = (stack.top==0?d : stack.data[top-1].data);
27   if (p->min > d) p->min = d;
28   top ++;
29 }
30 int MinStackPop(MinStack stack) {
31   if (stack.top == 0) error(“stack is empty!”);
32   return stack.data[--stack.top].data;
33 }
34 int MinStackMin(MinStack stack) {
35   if (stack.top == 0) error(“stack is empty!”);
36   return stack.data[stack.top-1].min;
37 }

4. 查找最小的k 个元素

    Tips: 使用堆排序进行K次运算即可得到K个元素

5. 给你10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数。要求下排每个数都是先前上排那十个数在下排出现的次数。

上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】
举一个例子,
数值: 0,1,2,3,4,5,6,7,8,9
分配: 6,2,1,0,0,0,1,0,0,0

数值: 0,1,2,3,4
分配: 2,1,2,0,0

6.翻转句子中单词的顺序。

    Tips: 先翻转整个序列,然后翻转单词

7.输入一个单向链表,输出该链表中倒数第k 个结点。链表的倒数第0 个结点为链表的尾指针。

    Tips: 先遍历得到链表长度,然后遍历(n-k-1)个节点得到

8. 两个无序数组,求两个数组的交集和并集

    Tips:以其中一个数组为基础,遍历另外一个数组。存在则放入交集中,不存在则放入并集中。 O(m*n)

9.输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 void find2Number(int a[], int n, int dest);
 6 
 7 int main(){
 8     int arr[] = {1,2,4,7,11,15};
 9     int size = 6;
10     find2Number(arr,size,18);
11 
12     return 0;
13 }
14 
15 void find2Number(int a[], int n, int dest) {
16   int *f = a, *e=a+n-1;
17   int sum = *f + *e;
18   while (sum != dest && f < e) {
19     if (sum < dest)
20         sum = *(++f) + *e;
21     else
22         sum = *f + *(--e);
23   }
24   if (sum == dest)
25       cout << *f << " " << *e << endl;
26 }

10.在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。

 1 char firstSingle(char * str) {
 2   int a[255];
 3   memset(a, 0, 255*sizeof(int));
 4   char *p=str;
 5   while (*p!=’\0’) {
 6     a[*p] ++;
 7     p++;
 8   }
 9   p = str;
10   while (*p!=’\0’) {
11     if (a[*p] == 1) return *p;
12   }
13   return ‘\0’; // this must the one that occurs exact 1 time.
14 }

11. 输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串"345",则输出整数345。

 1 int atoi(char * str) {
 2   int neg = 0;
 3   char * p = str;
 4   if (*p == ‘-’) {
 5     p++; neg = 1;
 6   } else if (*p == ‘+’) {
 7     p++;
 8   }
 9   int num = 0;
10   while (*p != ‘\0’) {
11     if (*p>=0 && *p <= 9) {
12       num = num * 10 + (*p-’0’);
13     } else {
14       error(“illegal number”);
15     }
16     p++;
17   }
18   return num;
19 }

12.

13.

14.

15.

16.

17.

18.

19.

20.

 

程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦

程序员编程艺术第一~十章集锦与总结(教你如何编程)

 

posted @ 2012-10-06 17:19  hanyuanbo  阅读(254)  评论(0编辑  收藏  举报