1. 知识:  
  2.   1.数据结构中对象的定义,存储的表示及操作的实现.  
  3.   2.线性:线性表、栈、队列、数组、字符串(广义表不考)  
  4.    树:二叉树  
  5.    集合:查找,排序  
  6.    图(不考)  
  7. 能力:  
  8.   分析,解决问题的能力  
  9. 过程:  
  10.   ● 确定问题的数据。  
  11.   ● 确定数据间的关系。  
  12.   ● 确定存储结构(顺序-数组、链表-指针)  
  13.   ● 确定算法  
  14.   ● 编程  
  15.   ● 算法评价(时间和空间复杂度,主要考时间复杂度)  
  16.  
  17. 一、数组  
  18.   1、存放于一个连续的空间  
  19.   2、一维~多维数组的地址计算方式  
  20.    已知data[0][0]的内存地址,且已知一个元素所占内存空间S求data[i][j]在内存中的地址。  
  21.    公式:(add+(i*12+j)*S)(假设此数组为data[10][12])  
  22.   注意:起始地址不是data[0][0]时候的情况。起始地址为data[-3][8]和情况;  
  23.   3、顺序表的定义  
  24.    存储表示及相关操作  
  25.   4、顺序表操作中时间复杂度估计  
  26.   5、字符串的定义(字符串就是线性表),存储表示  
  27.    模式匹配算法(简单和KMP(不考))  
  28.   6、特殊矩阵:存储方法(压缩存储(按行,按列))  
  29.    三对角:存储于一维数组  
  30.    三对角问题:已知Aij能求出在一维数组中的下标k;已知下标k求Aij。  
  31.   7、稀疏矩阵:定义,存储方式:三元组表、十字链表(属于图部分,不考)  
  32.  
  33.   算法  
  34.   ● 数组中元素的原地逆置; 对换  
  35.   ● 在顺序表中搜索值为X的元素;  
  36.   ● 在有序表中搜索值为X的元素;(折半查找)  
  37.   ● 在顺序表中的第i个位置插入元素X;  
  38.   ● 在顺序表中的第i个位置删除元素X;  
  39.   ● 两个有序表的合并;算法?  
  40.   线性表数据结构定义:  
  41.    Typedef struct {  
  42.     int data[max_size];  
  43.     int len;  
  44.    }linear_list;  
  45.   ● 模式匹配  
  46.   ● 字符串相加  
  47.   ● 求子串  
  48.   ● (i,j)<=>K 注意:不同矩阵所用的公式不同;  
  49.   ● 稀疏矩阵的转置(两种方式,后种为妙)  
  50.   ● 和数组有关的算法  
  51.  
  52.  
  53. --------------------------------------------------------------------------------  
  54.  
  55.   例程:求两个长整数之和。  
  56.   a=13056952168  
  57.   b=87081299  
  58.   数组:  
  59.   a[]:1 3 0 5 6 9 5 2 1 6 8  
  60.   b[]:8 7 0 8 1 2 9 9  
  61.   由于以上的结构不够直观(一般越是直观越容易解决) 将其改为:  
  62.   a[]:11 8 6 1 2 5 9 6 5 0 3 1 a[0]=11(位数)  
  63.   b[]: 8 9 9 2 1 8 0 7 8 0 0 0 b[0]=8  
  64.   c进位 0 1 1 0 0 1 1 1 1 0 0  
  65.   c[]:11 7 6 4 3 3 0 4 4 2 3 1 c[0]的值(C位数)由c[max_s+1]决定!  
  66.   注意:在求C前应该将C(max_s+1)位赋0.否则为随机数; 较小的整数高位赋0.  
  67.   算法:已知a,b两个长整数,结果:c=a+b;  
  68.   总共相加次数: max_s=max(a[],b[])  
  69.   程序:  
  70.   for(i=1;i<=max_s;i++) {  
  71.    k=a[i]+b[i]+c[i];  
  72.    c[i]=k%10;  
  73.    c[i+1]=k/10;  
  74.   }  
  75.   求c位数:  
  76.   if(c[max_s+1]==0)  
  77.    c[0]=max_s;  
  78.   else 
  79.    c[0]=max_s+1;  
  80.   以下代码是我编的(毕竟是初学者.不太简洁大家不要见怪!):  
  81.   /*两长整数相加*/  
  82.    #include<stdio.h>  
  83.    #include<string.h>  
  84.   #define PRIN printf("\n");  
  85.  
  86.   int flag=0; /*a[0]>b[0]?1:0*/  
  87.  
  88.   /* max(a[],b[]) {}*/  
  89.  
  90.   change(char da[],char db[],int a[],int b[],int c[]) {  
  91.    int i;  
  92.    if(a[0]>b[0]) {  
  93.     for(i=1;i<=a[0];a[i]=da[a[0]-i]-'0',i++); /*a[0]-'0' so good!*/  
  94.     for(i=1;i<=b[0];b[i]=db[b[0]-i]-'0',i++);  
  95.     for(i=b[0]+1;i<=a[0];b[i]=0,i++);  
  96.     for(i=1;i<=a[0]+1;c[i]=0,i++);  
  97.     flag=1;  
  98.    }  
  99.    else {  
  100.     for(i=1;i<=b[0];b[i]=db[b[0]-i]-'0',i++);  
  101.     for(i=1;i<=a[0];a[i]=da[a[0]-i]-'0',i++);  
  102.     for(i=a[0]+1;i<=b[0];a[i]=0,i++);  
  103.     for(i=1;i<=b[0]+1;c[i]=0,i++);  
  104.    }  
  105.   }  
  106.  
  107.   add(int a[],int b[],int c[]) {  
  108.    int i,sum;  
  109.    if(flag==1) {  
  110.     for(i=1;i<=a[0];i++) {  
  111.      sum=a[i]+b[i]+c[i];  
  112.      c[i+1]=sum/10;  
  113.      c[i]=sum%10;  
  114.     }  
  115.     if(c[a[0]+1]==0)  
  116.      c[0]=a[0];  
  117.     else 
  118.      c[0]=a[0]+1;  
  119.    }  
  120.    else {  
  121.     for(i=1;i<=b[0];i++) {  
  122.      sum=a[i]+b[i]+c[i];  
  123.      c[i+1]=sum/10;  
  124.      c[i]=sum%10;  
  125.     }  
  126.     if(c[b[0]+1]==0)  
  127.      c[0]=b[0];  
  128.     else 
  129.      c[0]=b[0]+1;  
  130.    }  
  131.   }  
  132.  
  133.   void print(int m[]) {  
  134.    int i;  
  135.    for(i=m[0];i>=1;i--)  
  136.     printf("%d,",m[i]); PRIN  
  137.   }  
  138.  
  139.   main(){  
  140.    int s;  
  141.    int a[20],b[20],c[20];  
  142.    char da[]={"123456789"};  
  143.    char db[]={"12344443"};  
  144.    a[0]=strlen(da);  
  145.    b[0]=strlen(db);  
  146.    printf("a[0]=%d\t",a[0]);  
  147.    printf("b[0]=%d",b[0]); PRIN  
  148.    change(da,db,a,b,c);  
  149.    printf("flag=%d\n",flag); PRIN  
  150.    printf("-----------------\n");  
  151.    if(flag==1) {  
  152.     print(a); PRIN  
  153.     s=abs(a[0]-b[0]);  
  154.     printf("+");  
  155.      for(s=s*2-1;s>0;s--)  
  156.       printf(" ");  
  157.       print(b); PRIN  
  158.    }  
  159.    else {  
  160.     s=abs(a[0]-b[0]);  
  161.     printf("+");  
  162.     for(s=s*2-1;s>0;s--)  
  163.      printf(" ");  
  164.      print(a); PRIN  
  165.      print(b); PRIN  
  166.    }  
  167.    add(a,b,c);  
  168.    printf("-----------------\n");  
  169.    print(c);  
  170.   }  
  171.  
  172. 时间复杂度计算:  
  173.   ● 确定基本操作  
  174.   ● 计算基本操作次数  
  175.   ● 选择T(n)  
  176.   ● lim(F(n)/T(n))=c  
  177.   ● 0(T(n))为时间复杂度  
  178.   上例子的时间复杂度为O(max_s);  
  179.  
  180.  
  181. --------------------------------------------------------------------------------  
  182.  
  183. 二:链表  
  184.   1、知识点  
  185.   ●逻辑次序与物理次序不一致存储方法;  
  186.   ●单链表的定义:术语(头结点、头指针等)  
  187.   ●注意带头结点的单链表与不带头结点的单链表区别。(程序员考试一般不考带头结点,因为稍难理解)  
  188.   ●插入、删除、遍历(p==NULL表明操作完成)等操作  
  189.   ● 循环链表:定义,存储表示,操作;  
  190.   ● 双向链表:定义,存储方法,操作;  
  191.   单链表和循环链表区别在最后一个指针域值不同。  
  192.   2、操作  
  193.   ●单链表:插入X,删除X,查找X,计算结点个数  
  194.   ●单链表的逆置(中程曾考)  
  195.   head->NULL/p->a1/p->a2/p->a3/p……an/NULL 注:p代表指针;NULL/p代表头结点  
  196.   =》 head->NULL/p->an/p->an-1/p->an-2/p……a1/NULL 
  197.   ●循环链表的操作:插入X,删除X,查找X,计算结点个数;  
  198.     用p=head->next来判断一次计算结点个数完成;  
  199.   程序段如下:  
  200.   k=0;  
  201.   do{  
  202.    k++;  
  203.    p=p->next;  
  204.   }while(p!=head->next);  
  205.   ● 双向链表  
  206.   ●多项式相加  
  207.   ● 有序链表合并  
  208.  
  209.  
  210. --------------------------------------------------------------------------------  
  211.  
  212.   例程:已知两个字符串S,T,求S和T的最长公子串;  
  213.   1、逻辑结构:字符串  
  214.   2、存储结构:数组  
  215.   3、算法: 精化(精细化工)**老顽童注:此处“精细化工”说明好像不对!  
  216.   s="abaabcacb" 
  217.   t="abdcabcaabcda" 
  218.   当循环到s.len-1时,有两种情况:s="abaabcacb"、s="abaabcacb" 
  219.       s.len-2时,有三种情况:s="abaabcacb"、s="abaabcacb"、s="abaabcacb" 
  220.        .  
  221.        .  
  222.        .  
  223.       1 s.len种情况  
  224.   程序思路:  
  225.   tag=0 //没有找到  
  226.   for(l=s.len;l>0&&!tag;l--) {  
  227.    判断长度为l的s中的子串是否为t的子串;  
  228.    若是:tag=1;  
  229.   }  
  230.  
  231.   长度为l的s的子串在s中有(s.len-l+1)个。  
  232.   子串0: 0~l-1  
  233.     1:    1~l        
  234.     2:    2~l+1        
  235.     3:    3~l+2  
  236.      ……  
  237.      ……  
  238.     s.len-l: s.len-l~s.len-1  
  239.   由上面可得:第j个子串为j~l+j-1。  
  240.  
  241.   判断长度为l的s中的子串是否为t的子串:  
  242.   for(j=0;j<s.len-l+1&&!tag;j++){  
  243.    判断s中长度为l的第j个子串是否为t的子串;  
  244.    如果是:tag=1;  
  245.   }  
  246.  
  247.   模式结构:  
  248.   tag=0;  
  249.   for(l=s.len;l>0&&tag==0;l--) {  
  250.    for(j=0;j<s.len-l+1&&!tag;j++) {  
  251.     ?? 用模式匹配方法确定s[j]~s[l+j-1]这个字符串是否为t的子串; //好好想想  
  252.      若是,tag=1;  
  253.    }  
  254.   }  
  255.  
  256.  
  257. 第二天 时间:9/18/2003  
  258.  
  259.   转眼又过了一周了,前面一周里面我编了一些程序:链表,长整型数相加,三元组表转置以及一些简单的函数.其实有些算法想想是很简单,不过写起来还是需要一定耐心和C基础的,如果你自己觉得各算法都很懂了,不妨开机编编试试.或许会有一些新的发现与体会.  
  260. 栈和队列  
  261.   1、知识点:  
  262.   ● 栈的定义:操作受限的线性表  
  263.   ● 特点:后进先出  
  264.   ● 栈的存储结构:顺序,链接  
  265.    / push(s,d)  
  266.   ● 栈的基本操作:  
  267.    \ pop(s)  
  268.  
  269.   栈定义:  
  270.   struct {  
  271.    datatype data[max_num];  
  272.    int top;  
  273.   };  
  274.  
  275.   ●队列定义  
  276.   特点:先进先出  
  277.   /入队列 in_queue(Q,x)  
  278.   ●队列的操作:  
  279.   \出队列 del_queue(Q)  
  280.   ●队列存储结构:  
  281.   链队列:  
  282.   Typedef struct node{  
  283.    Datatype data;  
  284.    Struct node *next;  
  285.   }NODE;  
  286.   Typedef struct {  
  287.    NODE *front;  
  288.    NODE *rear;  
  289.   }Queue;  
  290.   顺序队列:  
  291.   struct {  
  292.    datatype data[max_num];  
  293.    int front,rear;  
  294.   };  
  295.   问题:  
  296.   队列ó线性表  
  297.   假溢出<=循環队列  
  298.   队列满,队列空条件一样<=浪费一个存储空间  
  299.  
  300.   递归  
  301.   定义:问题规模为N的解依赖于小规模问题的解。问题的求解通过小规模问题的解得到。  
  302.   包括二个步骤:  
  303.   1) 递推 6!=>5!=>4!=>3!=>2!=>1!=>0!  
  304.   2) 回归 720<=120<=24<=6 <=2 <=1 <=0  
  305.   递归工作栈实现递归的机制。  
  306.  
  307.   2、有关算法:  
  308.   1) 顺序,链表结构下的出栈,入栈  
  309.   2) 循環,队列的入队列,出队列。  
  310.   3) 链队列的入队列,出队列。  
  311.   4) 表达式计算:后缀表达式 35+6/4368/+*-  
  312.           中缀表达式 (3+5)/6-4*(3+6/8)  
  313.  
  314.            
  315.  
  316.   由于中缀比较难处理,计算机内一般先将中缀转换为后缀。  
  317.   运算:碰到操作数,不运算,碰到操符,运算其前两个操作数。  
  318.    中缀=>后缀  
  319.   5) 迷宫问题  
  320.   6) 线性链表的递归算法 一个链表=一个结点+一个链表  
  321.   int fuction(NODE *p) {  
  322.    if(p==NULLreturn 0;  
  323.    else return(function(p->next));  
  324.   }  
  325.  
  326.   树与二叉树  
  327.   一、 知识点:  
  328.   1. 树的定义: data_struct(D,R);  
  329.   其中:D中有一个根,把D和出度去掉,可以分成M个部分.  
  330.   D1,D2,D3,D4,D5…DM  
  331.   R1,R2,R3,R4,R5…RM  
  332.   而子树Ri形成树.  
  333.   1) 递归定义 高度  
  334.  
  335.  
  336.    2) 结点个数=1  
  337.     
  338.     O    --0  
  339.  
  340. O    O  --1  
  341.  
  342. O  O  O  O --2  
  343.  
  344.  
  345. 此树的高度为2  
  346.  
  347.  
  348.   2.二叉树定义:   
  349.   结点个数>=0 .  
  350.   3. 术语:左右孩子,双亲,子树,度,高度等概念.  
  351.   4. 二叉树的性质  
  352.   ●层次为I的二叉树 I层结点 2I 个  
  353.   ●高度为H的二叉树结点 2H+1-1个  
  354.   ●H(点)=E(边)+1  
  355.   ●个数为N的完全二叉树高度为|_LOG2n_|  
  356.   ●完全二叉树结点编号:从上到下,从左到右.  
  357.  
  358. i结点的双亲: |_i/2_| |_i-1/2_|    1    
  359. i结点的左孩子: 2i 2i+1  2    3  
  360. i结点的右孩子: 2i+1 2i+2 4  5  6  7  
  361. (根) 1为起点 0为起点        
  362.  
  363.   二叉树的存储结构:  
  364.     1) 扩展成为完全二叉树,以一维数组存储。  
  365.  
  366.      A     
  367.   B      C  
  368. D      E  F  
  369. G  H    I    
  370.  
  371. 数组下标 0 1 2 3 4 5 6 7 8 9 10 11 12  
  372. 元素 A B C D E F G H         I  
  373.  
  374.     2) 双亲表示法  
  375.  
  376. 数组下标 0 1 2 3 4 5 6 7 8  
  377. 元素 A B C D E F G H I  
  378. 双亲 -1 0 0 1 2 2 3 3 4  
  379.  
  380.     3) 双亲孩子表示法  
  381.  
  382. 数组下标 0 1 2 3 4 5 …  
  383. 元素 A B C D E F …  
  384. 双亲 -1 0 0 1 2 2 …  
  385. 左子 1 3 4       …  
  386. 右子 2 -1 5       …  
  387.  
  388.   结构:  
  389.     typedef struct {  
  390.      datatype data;  
  391.      int parent;  
  392.      int lchild;  
  393.      int rchild;  
  394.     }NODE;  
  395.     NODE tree[N]; // 生成N个结点的树  
  396.     4) 二叉链表  
  397.     5) 三叉链表  
  398.     6) 哈夫曼树  
  399.   5.二叉树的遍历  
  400.    先根 \  
  401.    中根 栈 中根遍历(左子树)根(右子树),再用相同的方法处理左子树,右子树.  
  402.    后根 /  
  403.    先,中序已知求树:先序找根,中序找确定左右子树.  
  404.    层次遍历(队列实现)  
  405.   6.线索二叉树(穿线树)  
  406.    中序线索二树树目的:利用空指针直接得到中序遍历的结果.  
  407.    手段(方法):左指针为空,指向前趋,右指针为空,指向后继.  
  408.   结点结构:  
  409.  
  410. ltag Lch Data rch rtag  
  411.  
  412.   Ltag=0,lch指向左孩子,ltag=1,指向前趋结点  
  413.   Rtag=0,rch指向右孩子;rtag=1,指向后继结点  
  414.   中序遍历: 1) 找最左结点(其左指针为空)  
  415.     2) 当该结点的rtag=1,该结点的rch指向的就为后继  
  416.     3) 当rtag=0,后继元素为右子树中最左边那个  
  417.   N个结点的二树有空指针N+1个  
  418.  
  419.   周六我去了周SIR的办公室,他很热情,我问的是中序线索化二叉树的问题(递归),关于这个问题我会在以后的笔记中作重点补充。我在这学校从来没有碰到过像他这样热情的老师,真的,大一的时候我们学校就开了C,当时我就连#include<stdio.h>这句话的意思都不晓得,别说是让我写程序了(到这份上也不怕把丑事都抖出来了:《数据结构》的课程设计也是哈科大的littlebob兄帮我做的,很遗憾,他高程就差几分,希望他早日成功,我们都要向他学习)等于说我的C知识九成都是在大二下学期的时候学的。而且全是自学的。拿这个周末来说吧。我三天时间就看完了一本C语言大全。当然,并不是从头到尾,只是根据自己的实际情况,重点是指针和数据结构那块。C最要的便是指针。程序员考试下午试题最重要的便是递归问题(1~2道,没有掌握就没希望了哦)。我说这些并不是为了表明自己多么用功,只是希望每位"学者"都有所侧重。  
  420.  
  421.  
  422. 第三天 时间:9/23/2003  
  423.  
  424.  
  425.   排序查找是我自己觉得最头疼的算法了,常搞混去的啊.不知道各位学得如何,如果不错,还请告诉我一些经验!  
  426.  
  427. 查找  
  428.  
  429. 一、 知识点    /静态查找->数组      
  430.   1、 什么是查找  
  431.           \动态查找->链树  
  432.   ●顺序查找,时间复杂度 O(n)  
  433.   ●折半查找:条件:有序;时间复杂度 O(nlog2n) (时间复杂度实际上是查找树的高度)  
  434.   ●索引查找:条件:第I+1块的所有元素都大于第I块的所有元素。  
  435.    算法:根据index来确定X所在的块(i) 时间复杂度:m/2      
  436.       在第I块里顺序查找X      时间复杂度:n/2  
  437.    总的时间复杂度:(m+n)/2  
  438.   ●二叉排序树 1)定义:左子树键值大于根节点键值;右子树键值小于根的键值,其左右子树均为二叉排序树。   
  439.          2)特点:中序遍历有序->(删除节点用到此性质)  
  440.          3)二叉排序树的查找:如果根大于要查找的树,则前左子树前进,如果根小于要查找的树,则向右子树前进。  
  441.          4)结点的插入->二叉排序树的构造方法  
  442.          5)结点删除(难点)  1、右子树放在左子树的最右边  
  443.                     2、左子树放在右子树的最左边  
  444.   ●avl树(二叉平衡树):左右子树高度只能差1层,即|h|<=1其子树也一样。  
  445.   ●B树:n阶B树满足以下条件 1)每个结点(除根外)包含有N~2N个关链字。                2)所有叶子节点都在同一层。  
  446.                 3)B树的所有子树也是一棵B树。  
  447.    特点:降低层次数,减少比较次数。  
  448.  
  449. 排序  
  450. 一、知识点  
  451.   1、排序的定义  
  452.          /内排序:只在内存中进行  
  453.   2、排序的分类  
  454.          \外排序:与内外存进行排序   
  455.    内排序:   /直接插入排序  
  456.     1)插入排序  
  457.           \shell排序  
  458.           /冒泡排序  
  459.     2)交换排序   
  460.           \快速排序  
  461.            /简单选择排序  
  462.     3)选择排序 堆  
  463.            \ 锦标赛排序  
  464.     4)归并排序(二路)  
  465.     5)基数排序(多关链字排序)  
  466.   3、时间复杂度(上午题目常考,不会求也得记住啊兄弟姐妹们!)  
  467.  
  468.          * * * * * * 15 * * * 15 * * *  
  469.     /稳定   * * * * * * * * 15 15 * * * *(前后不变)   
  470.   排序    
  471.     \ 不稳定 * * * * * * * * 15 15 * * * *(前后改变)  
  472.   经整理得:选择、希尔、堆、快速排序是不稳定的;直接插入、冒泡、合并排序是稳定的。  
  473.  
  474.   ●锦标赛排序方法: 13  16  11  18  21  3  17  6  
  475.              \  /   \  /   \  /    \ /  
  476.               13     11     3      6  
  477.               \     /      \     /  
  478.                  11           3  
  479.                   \           /  
  480.                         3(胜出,将其拿出,并令其为正无穷&Go On)  
  481.  
  482.   ●归并排序方法:  13  16  11  18  21  3  17  6  
  483.              \  /   \  /   \  /   \  /  
  484.              13,16    11,18    3,21    6,17  
  485.               \     /      \     /  
  486.               11,13,16,18       3,6,17,21  
  487.                  \           /  
  488.                   3,6,11,13,16,17,18,21  
  489.  
  490.   ●shell排序算法:1)定义一个步长(或者说增量)数组D[m];其中:D[m-1]=1(最后一个增量必须为1,否则可能不完全)  
  491.          2)共排m趟,其中第i趟增量为D[i],把整个序列分成D[i]个子序列,分别对这D[i]个子序列进行直接插入排序。  
  492.          程序如下: for(i=0;i<m;i++)  
  493.               {for(j=0;j<d[i];j++)  
  494.                {对第i个子序列进行直接插入排序;   
  495.                   注意:下标之差为D[i];  
  496.                }  
  497.               }  
  498.  
  499.   ●快速排序 ( smaller )data ( bigger )  
  500.    d[] i-> 13 16 11 18 21 3 17 6 24 8 <-j  
  501.    先从后往前找,再从前往后找。   
  502.    思想:空一个插入一个,i空j挪,j空i挪(这里的i,j是指i,j两指针所指的下标)。  
  503.    一次执行算法:1)令temp=d[0](枢纽),i=0,j=n-1;  
  504.            2)奇数次时从j位置出发向前找第一个比temp小的元素,找到后放到i的位置(d[i]=d[j];i++;) i往后挪。  
  505.           3)偶数次时从i开始往后找第一个比temp大的数,(d[j]=d[i];j--;)  
  506.           4)当i=j时,结束循环。d[i]=temp;  
  507.   再用递归对左右进行快速排序,因为快速排序是一个典型的递归算法。  
  508.  
  509.   ●堆排序   
  510.     定义:d[n]满足条件:d[i]<d[2i+1]&&d[i]<d[2i+2] 大堆(上大下小)  
  511.               d[i]>d[2i+1]&&d[i]>d[2i+2] 小堆(上小下大)  
  512.     判断是否为堆应该将其转换成树的形式。总共排序n-1次  
  513.  
  514.   调整(重点)  
  515.    程序: flag=0;  
  516.       while(i<=n-1) {  
  517.        if(d[i]<d[2*i+1])||(d[i]<d[2*i+2]))  
  518.        { if(d[2*i+1]>d[2*i+2]) 8 24 {d[i]<->d[2*i+1]; 24 21 -> 8 21  
  519.         i=2*i+1;  
  520.         else {  
  521.          d[i]<->d[2*i+2];  
  522.          i=2*i+2;  
  523.         }  
  524.        }  
  525.        else 
  526.         flag=1; //是堆  
  527.       }  
  528.  
  529.   堆排序过程:  
  530.  
  531.   ●基数排序(多关键字排序)  
  532.   扑克: 1) 大小->分配  
  533.      2) 花色->分配,收集  
  534.   思想:分配再收集.  
  535.   构建链表:链表个数根据关键字取值个数有关.  
  536.   例:将下面九个三位数排序:  
  537.     321 214 665 102 874 699 210 333 600  
  538.    定义一个有十个元素的数组:  
  539.  
  540.           a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]  
  541.    第一趟(个位): 210 321 102 333 214 665         699  
  542.           600         874  
  543.        结果: 210 600 321 102 333 214 874 665 699  
  544.    第二趟(十位): 600 210 321    333    665 874    699  
  545.           102 214  
  546.        结果: 600 102 210 214 321 333 665 874 699  
  547.    第三趟(百位): 102 210 321      600    874  
  548.              214 333      665  
  549.                        699  
  550.        结果: 102 210 214 321 333 600 665 699 874(排序成功)  
  551.  
  552.   最近在看一位程序员的笔记,也挺不错的啊.这应当是他的网站.他总说他的网站人气不够,现在顺便就帮他宣传一下啦!http://zhgpa.vicp.net/bbs,大家有时间多去去哦,呵呵!谢谢大伙支持!另外,还向大家推荐一个网站:http://kaowang.com/,挺不错的一个考试网站。学到不少东东啊!  
  553.  
  554.  
  555. 八大类算法  
  556.  
  557.   程序员考试下午试题最后一道一般是八大类算法里头的.大家尤其要注意的是递归,因为近几年都考了,而且有的还考两题。可以说如果我们不掌握递归就没有掌握C,况且递归是C里的难点。为了控制合格率,程序员考试不会让我们轻松过关的,为了中国软件业,我想也应该这样啊。  
  558.     /数据结构(离散)  
  559.   迭代  
  560.     \数值计算(连续)  
  561.   枚举 策略好坏很重要  
  562.   递推  
  563.   递归  
  564.   回溯  
  565.   分治  
  566.   贪婪  
  567.   动态规划  
  568.   其中:递推、递归、分治、动态规划四种算法思想基本相似。都是把大问题变成小问题,但技术上有差别。  
  569.  
  570.  
  571.  
  572. 第四天 时间:9/26/2003  
  573.  
  574. 枚举:  
  575.   背包问题:  
  576.   枚举策略:1)可能的方案:2N  
  577.        2)对每一方案进行判断.  
  578.  
  579.   枚举法一般流程:  
  580.     while(还有其他可能方案)  
  581.     { 按某种顺序可难方案;  
  582.      检验方案;  
  583.      if(方案为解)  
  584.       保存方案;  
  585.      }  
  586.     }  
  587.   枚举策略:  
  588.   例:把所有排列枚举出来 P6=6!.  
  589.    Min:123456  
  590.    Max:654321  
  591.    a1a2a3a4a5a6=>?(下一排列)=>?  
  592.    比如:312654的下和种情况=>314256  
  593.  
  594. 递归  
  595.   递归算法通常具有这样的特征:为求解规模为N的问题,设法将它分解成一些规模较小的问题,然后从这些较小问题的解能方便地构造出题目所需的解。而这些规模较小的问题也采用同样的方法分解成规模更小的问题,通过规模更小的问题构造出规模校小的问题的解,如此不断的反复分解和综合,总能分解到最简单的能直接得到解的情况。  
  596.   因此,在解递归算法的题目时,要注意以下几点:  
  597.   1) 找到递归调用的结束条件或继续递归调用条件.  
  598.   2) 想方设法将处理对象的规模缩小或元素减少.  
  599.   3) 由于递归调用可理解为并列同名函数的多次调用,而函数调用的原则是一层一层调用,一层一层返回.因此,还要注意理解调用返回后的下一个语句的作用.在一些简单的递归算法中,往往不需要考虑递调用返回后的语句处理.而在一些复杂的递归算法中,则需要考虑递归调用返回后的语句处理和进一步的递归调用.  
  600.   4) 在读递归程序或编写递归程序时,必须要牢记递归函数的作用,这样便于理解整个函数的功能和知道哪儿需要写上递归调用语句.当然,在解递归算法的题目时,也需要分清递归函数中的内部变量和外部变量.  
  601.   表现形式:  
  602.   ●定义是递归的(二叉树,二叉排序树)  
  603.   ●存储结构是递归的(二叉树,链表,数组)  
  604.   ●由前两种形式得出的算法是递归的  
  605.   一般流程: function(variable list(规模为N))  
  606.    { if(规模小,解已知) return 解;  
  607.     else {  
  608.      把问题分成若干个部分;  
  609.      某些部分可直接得到解;  
  610.      而另一部分(规模为N-1)的解递归得到;  
  611.     }  
  612.   }  
  613.   例1:求一个链表里的最大元素.  
  614.   大家有没想过这个问题用递归来做呢?  
  615.   非递归方法大家应该都会哦?  
  616.     Max(nodetype *h) {  
  617.      nodetype *p;  
  618.      nodetype *q; //存放含最大值的结点  
  619.      Int max=0;  
  620.      P=h;  
  621.      While(p!=NULL){  
  622.       if (max<p->data) {  
  623.        max=p->data;  
  624.        q=p;  
  625.       }  
  626.       p=p->next;  
  627.      }  
  628.      return q;  
  629.     }  
  630.   下面真经来了,嘻嘻嘻~~~  
  631.     *max(nodetype *h) {  
  632.      nodetype *temp;  
  633.      temp=max(h->next);  
  634.      if(h->data>temp->data)  
  635.       return h;  
  636.      else 
  637.       return temp;  
  638.     }  
  639.   大家有空想想下面这个算法:求链表所有数据的平均值(我也没试过),不许偷懒,用递归试试哦!  
  640.   递归程序员考试题目类型:1)就是链表的某些操作(比如上面的求平均值)  
  641.               2)二叉树(遍历等)  
  642.  
  643.   例2.判断数组元素是否递增  
  644.      int jidge(int a[],int n) {  
  645.       if(n==1) return 1;  
  646.       else 
  647.        if(a[0]>a[1]) return 0;  
  648.        else return jidge(a+1,n-1);  
  649.      }  
  650.  
  651.   例3.求二叉树的高度(根据二叉树的递归性质:(左子树)根(右子树))  
  652.      int depth(nodetype *root) {  
  653.       if(root==NULL)  
  654.        return 0;  
  655.       else {  
  656.        h1=depth(root->lch);  
  657.        h2=depth(root->rch);  
  658.        return max(h1,h2)+1;  
  659.       }  
  660.       }  
  661.   自己想想求二叉树结点个数(与上例类似)  
  662.  
  663.   例4.已知中序遍历和后序遍历,求二叉树.  
  664.    设一二叉树的:  
  665.    中序 S:E D F B A G J H C I  
  666.       ^start1 ^j ^end1  
  667.    后序 T:E F D B J H G I C A  
  668.       ^start2 ^end2  
  669.     node *create(char *s,char *t, int start1,int start2,int end1,int end2)  
  670.     { if (start1>end1) return NULL; //回归条件  
  671.      root=(node *)malloc(sizeof(node));  
  672.      root->data=t[end2];  
  673.      找到S中T[end2]的位置为 j  
  674.      root->lch=create(S,T,s1,j-1,start1,j+start2-start1-1);  
  675.      root->rch=create(S,T,j+1,end1,j+start2-start1,end2-1);  
  676.      return root;  
  677.     }  
  678.  
  679.   例5.组合问题  
  680.    n 个数: (1,2,3,4,…n)求从中取r个数的所有组合.  
  681.    设n=5,r=3;  
  682.    递归思想:先固定一位 5 (从另四个数当中选二个)  
  683.               5,4 (从另三个数当中选一个)  
  684.               5,4,3 (从另二个数当中选零个)  
  685.    即:n-2个数中取r-2个数的所有组合  
  686.      …  
  687.   程序:  
  688.    void combire(int n,int r) {  
  689.     for(k=n;k>=n+r-1;k--) {  
  690.      a[r]=k;  
  691.      if(r==0) 打印a数组(表示找到一个解);  
  692.      else combire(n-1,r-1);  
  693.     }  
  694.    }  
  695.  
  696.  
  697. 第五天 9/28/2003  
  698.  
  699.  
  700. 回溯法:  
  701.   回溯跟递归都是程序员考试里常出现的问题,大家必须掌握!  
  702.   回溯法的有关概念:  
  703.   1) 解答树:叶子结点可能是解,对结点进行后序遍历.  
  704.   2) 搜索与回溯  
  705.   五个数中任选三个的解答树(解肯定有三层,至叶子结点):  
  706.                ROOT 虚根  
  707.         /      /    |  \  \  
  708.         1      2     3  4   5  
  709.     /  |  |  \  / | \    /\  |  
  710.     2  3  4  5 3 4 5  4 5  5  
  711.    /|\  /\ |  /\ | |  
  712.    3 4 5 4 5 5 4 5 5 5  
  713.  
  714.   回溯算法实现中的技巧:栈  
  715.   要搞清回溯算法,先举一个(中序遍历二叉树的非递归算法)来说明栈在非递归中所起的作用。  
  716.       A 过程:push()->push()->push()->push()栈内结果:ABDE(E为叶子,结束进栈)  
  717.      / \   pop()   ABD(E无右孩子,出栈)  
  718.      B  C   pop()   AB(D无右孩子,出栈)  
  719.     /\     pop()   A(B有右孩子,右孩子进栈)  
  720.     D F     .      .  
  721.    / /\     .      .  
  722.    E G H    .      .  
  723.   /        .      .  
  724.   I        最后结果: EDBGFIHAC  
  725.   简单算法:  
  726.     …  
  727.    if(r!=NULL) //树不空  
  728.    { while(r!=NULL)  
  729.     { push(s,r);  
  730.      r=r->lch;   //一直向左孩子前进  
  731.     }  
  732.     while(!empty(s)) // 栈非空,出栈  
  733.     { p=pop(s);  
  734.      printf(p->data);  
  735.      p=p->rch;   //向右孩子前进  
  736.      while(p!=NULL)  
  737.      { push(s,p);  
  738.       p=p->lch; //右孩子进栈  
  739.      }  
  740.     }  
  741.    } //这就是传说中的回溯,嘻嘻……没吓着你吧  
  742.  
  743.   5选3问题算法:  
  744.   思想: 进栈:搜索  
  745.   出栈:回溯  
  746.   边建树(进栈)边遍历(出栈)  
  747.   基本流程:  
  748.   太复杂了,再说我不太喜欢用WORD画图(有损形象),以后再整理!  
  749.  
  750.   程序: n=5;r=3  
  751.      ……  
  752.      init(s)  //初始化栈  
  753.      push(s,1) //根进栈  
  754.      while(s.top<r-1)&&(s.data[s.top]!=n) //有孩子  
  755.       push(s,s.data[s.top]+1); //孩子入栈  
  756.      while(!empty(s))  
  757.      { if(s.top=r-1)  
  758.       判断该"解"是否为解.  
  759.       x=pop(s); //保留x,判断是否为最大值n,如果是n,则出栈  
  760.       while(x==n)  
  761.       x=pop(s);  
  762.       push(s,x+1);  
  763.       while(s.top<r-1)&&(s.data[s.top]!=n)  
  764.       push(s,s.data[s.top]+1);  
  765.      }  
  766.  
  767.   背包问题: TW=20 , w[5]={6,10,7,5,8}  
  768.   解的条件:1) 该解答树的叶子结点  
  769.   2) 重量最大  
  770.   解答树如下:   ROOT  
  771.        / | | | \  
  772.           6 10   7   5  8  
  773.         / | | \  / | \  / \ |  
  774.         10 7 5 8 7 5 8 5  8 8  
  775.          | |      |  
  776.          5 8      8  
  777.   程序:  
  778.   temp_w 表示栈中重量和  
  779.   …  
  780.   init(s); //初始化栈  
  781.   i=0;  
  782.   While(w[i]>TW)  
  783.    i++;  
  784.    If(i==n) Return -1; //无解  
  785.    Else {  
  786.     Push(s,i);  
  787.     Temp_w=w[i];  
  788.     i++;  
  789.     while(i<n)&&(temp_w+w[i]<=TW)  
  790.      { push(s,i);  
  791.       temp_w+=w[i];  
  792.       i++;  
  793.     }  
  794.     max_w=0;  
  795.     while(!empty(s))  
  796.      { if(max_w<temp_w)  
  797.        max_w=temp_w;  
  798.        x=pop(s);  
  799.        temp_w-=w[x];  
  800.        x++;  
  801.        while(x<n)&&(temp_w+w[x]>TW)  
  802.         x++;  
  803.        while(x<n)  
  804.        { push(s,x);  
  805.         temp_w=temp_w+w[x];  
  806.         x++;  
  807.         while(x<n)&&(temp_w+w[x]>TW)  
  808.         x++;  
  809.        }  
  810.      }  
  811.   请大家思考:四色地图问题,比如给中国地图涂色,有四种颜色,每个省选一种颜色,相邻的省不能取同样的颜色.不许偷懒,不能选人口不多于xxxxW的"大国"哦!如果真的有一天台x湾x独立x了,下场就是这样了,一种颜色就打发了,不过台湾的程序员们赚到了,省事!呵呵。  
  812.  
  813. 贪婪法:  
  814.   不求最优解,速度快(以精确度换速度)  
  815.  
  816.   例:哈夫曼树,最小生成树  
  817.  
  818.   装箱问题:  
  819.   有n个物品,重量分别为w[n],要把这n个物品装入载重为TW的集装箱内,需要几个集装箱?  
  820.   思想1:对n个物品排序  
  821.   拿出第1个集装箱,从大到小判断能不能放。  
  822.   2 …  
  823.   3 …  
  824.   . …  
  825.   . …  
  826.   思想2: 对n个物品排序  
  827.   用物品的重量去判断是否需要一只新箱子,如果物品重量小于本箱子所剩的载重量,则装进去,反之则取一只新箱子。  
  828.  
  829.   程序:  
  830.   count=1;qw[0]=TW;  
  831.   for(i=0;i<n;i++)  
  832.   {  
  833.    k=0;  
  834.    while(k<count)&&(w[i]>qw[k])  
  835.     k++;  
  836.     if(w[i]<=qw[k])  
  837.      qw[k]=qw[k]-w[i];  
  838.      code[i]=k; //第i个物品放在第k个箱子内  
  839.     else 
  840.      {count++; //取一个新箱子  
  841.       qw[count-1]=TW-w[i];  
  842.       code[i]=count-1;  
  843.     }  
  844.   }  
  845.  
  846.   用贪婪法解背包问题:  
  847.   n个物品,重量:w[n] 价值v[i]  
  848.   背包限重TW,设计一个取法使得总价值最大.  
  849.   方法:  
  850.    0  1  2  3 … n-1  
  851.    w0  w1  w2  w3 … wn-1  
  852.    v0  v1  v2  v3 … vn-1  
  853.    v0/w0  …     v(n-1)/w(n-1) 求出各个物品的"性价比" 
  854.  
  855.   先按性价比从高到低进行排序  
  856.  
  857.   已知:w[n],v[n],TW  
  858.   程序:  
  859.   …  
  860.   for(I=1;I<n;I++)  
  861.    d[i]=v[i]/w[i]; //求性价比  
  862.    for(I=0;I<n;I++)  
  863.    { max=-1;  
  864.     for(j=0;j<n;j++)  
  865.     { if(d[j]>max)  
  866.      { max=d[j];x=j; }  
  867.     }   
  868.     e[i]=x;  
  869.     d[x]=0;  
  870.    }  
  871.    temp_w=0;temp_v=0;  
  872.   for(i=0;i<n;i++)  
  873.    { if(temp_w+w[e[i]]<=TW)  
  874.      temp_v=temp_v+v[e[v]];  
  875.   }  
  876.  
  877.  
  878. 分治法:  
  879.   思想:把规模为n的问题进行分解,分解成几个小规模的问题.然后在得到小规模问题的解的基础上,通过某种方法组合成该问题的解.  
  880.  
  881.   例:数轴上有n个点x[n],求距离最小的两个点.  
  882.   分:任取一点,可以把x[i]这n个点分成两个部分  
  883.   小的部分 分点 大的部分  
  884.     |_._.__.__.____._|__._._.__._.__._______._.__._._.__.___._____._|  
  885.   治:解=min{小的部分的距离最小值;  
  886.    大的部分的距离最小值;  
  887.    大的部分最小点和小的部分最大点这两点之差;}  
  888.  
  889.  
  890. 第六天(想起了儿时的《最后一课》^_^) 10/7/2003  
  891.  
  892.  
  893.   快考试了,老师没有多说什么,他只是给我们讲了讲近三年试题情况,并详细讲述了两道题目:一道递归,另一道回溯。不过今天不知怎么回事,我感觉特别累,也特别想睡觉。所以没什么感觉。这里就不说了,两道题目都有的,递归那题是2001年最后一题,回溯是在《程序员教程》P416,老师说高程曾经考过,有兴趣自己看看也能看懂的。老师特意为我们出了一份下午试题,我现在把他拿出来让大家参考参考。到这里,就到这里!  
  894.  
  895.  
  896. 程序员考试下午试题(模拟)  
  897.  
  898. 一、把一个字符串插入到另一个字符串的某个位置(指元素个数)之后  
  899.   char *insert(char *s,char *t,int position)  
  900.   { int i;  
  901.    char *target;  
  902.    if(position>strlen(t)) printf("error");  
  903.    else 
  904.    { for (i=0;i< (1) ;i++)  
  905.     { if (i<position)  
  906.      target[i]=s[i];  
  907.      else 
  908.      { if(i< (2) )  
  909.       target[i]=t[i];  
  910.       else (3) ;  
  911.      }  
  912.     }  
  913.    }  
  914.    return garget;  
  915.   }  
  916. 二、辗转相除法求两个正整数的最大公约数  
  917.   int f(int a,int b)  
  918.   { if (a==b) (4) ;  
  919.    else 
  920.    { if (a>b) return f(a-b,b);  
  921.     else (5) ;  
  922.    }  
  923.   }  
  924. 三、求一个链表的所有元素的平均值  
  925.   typedef struct { int num;  
  926.    float ave;  
  927.   }Back;  
  928.   typedef struct node{ float data;  
  929.    struct node *next;  
  930.   } Node;  
  931.  
  932.   Back *aveage(Node *head)  
  933.   { Back *p,*q;  
  934.    p=(Back *)malloc(sizeof(Back));  
  935.    if (head==NULL)  
  936.    { p->num=0;  
  937.     p->ave=0; }  
  938.    else 
  939.    { (6) ;  
  940.     p->num=q->num+1;  
  941.     (7) ; }  
  942.    retuen p;  
  943.   }  
  944.  
  945.   main()  
  946.   { Node *h; Back *p;  
  947.    h=create(); /*建立以h为头指针的链表*/  
  948.    if (h==NULL) printf("没有元素");  
  949.    else { p=aveage(h);  
  950.     printf("链表元素的均值为:%6f",p->ave);  
  951.    }  
  952.   }  
  953. 四、希尔排序  
  954.   已知待排序序列data[n];希尔排序的增量序列为d[m],其中d[]序列降序排列,且d[m-1]=1。其方法是对序列进行m趟排序,在第i趟排序中,按增量d[i]把整个序列分成d[i]个子序列,并按直接插入排序的方法对每个子序列进行排序。  
  955. 希尔排序的程序为:  
  956.   void shellsort(int *data,int *d,int n,int m)  
  957.   { int i,j;  
  958.    for (i=0;i<m;i++)  
  959.    for (j=0; (1) ;j++)  
  960.    shell( (2) );  
  961.   }  
  962.  
  963.   void shell(int *data,int d,int num,int n)  
  964.   { int i,j,k,temp;  
  965.    for (i=1; (3) ;i++)  
  966.    { j=0;  
  967.     temp=data[j+i*d];  
  968.     while ((j<i)&&( (4) ))  
  969.     j++;  
  970.     for (k=j;k<i;k++)  
  971.      data[k+1]=data[k];  
  972.     (5) ;  
  973.     (6) }  
  974.   }  
  975. 五、求树的宽度  
  976.   所谓宽度是指在二叉树的各层上,具有结点数最多的那一层上的结点总数。本算法是按层次遍历二叉树,采用一个队列q,让根结点入队列,最后出队列,若有左右子树,则左右子树根结点入队列,如此反复,直到队列为空。  
  977.   int Width(BinTree *T)  
  978.   { int front=-1,rear=-1; /* 队列初始化*/  
  979.    int flag=0,count=0,p;/*p用于指向树中层的最右边的结点,flag记录层中结点数的最大值。*/  
  980.    if(T!=Null)  
  981.    { rear++; (1) ; flag=1; p=rear;  
  982.    }  
  983.    while( (2) )  
  984.    { front++;  
  985.     T=q[front];  
  986.     if(T->lchild!=Null)  
  987.     { rear++; (3) ; count++; } //  
  988.      if(T->rchild!=Null)  
  989.      { rear++; q[rear]=T->rchild; (4) ; }  
  990.      if(front==p) /* 当前层已遍历完毕*/  
  991.      { if( (5) ) flag=countcount=0; //  
  992.       p=rear; /* p指向下一层最右边的结点*/  
  993.      }  
  994.    }  
  995.    return(flag);  
  996.   }  
  997. 六、区间覆盖  
  998.   设在实数轴上有n个点(x0,x1,……,xn-2,xn-1),现在要求用长度为1的单位闭区间去覆盖这n个点,则需要多少个单位闭区间。  
  999.   int cover(float x[ ], int num)  
  1000.   { float start[num],end[num];  
  1001.    int i ,j ,flag, count=0;  
  1002.    for (i=0;i<num;i++)  
  1003.    { flag=1;  
  1004.     for (j=0;j< (1) ;j++)  
  1005.     { if ((start[j]>x[i])&&(end[j]-x[i]<=1)) (2) ;  
  1006.      else if ( (3) ) end[j]=x[i];  
  1007.      else if ((x[i]>start[j])&&(x[i]<end[j])) flag=0;  
  1008.      if (flag) break;  
  1009.     }  
  1010.     if ( (4) )  
  1011.      { end[count]=x[i]; (5); count++; }  
  1012.    }  
  1013.    return count-1;  
  1014.   }  
  1015.   start[count]=x[i]  
  1016. 七、围棋中的提子  
  1017.   在围棋比赛中,某一方(假设为黑方)在棋盘的某个位置(i,j)下子后,有可能提取对方(白方的一串子)。以W[19][19]表示一个棋盘,若 W[i][j]=0表示在位置(i,j)上没有子,W[i][j]=1表示该位置上的是黑子,W[i][j]=-1表示该位置上是白子。可以用回溯法实现提子算法。  
  1018. 下列程序是黑棋(tag=1)下在(i,j)位置后判断是否可以吃掉某些白子,这些确定可以提掉的白子以一个线性表表示。  
  1019.   问题相应的数据结构有:  
  1020.   #define length 19 /*棋盘大小*/  
  1021.   #define max_num 361 /*棋盘中点的数量*/  
  1022.   struct position { int row; int col;  
  1023.   }; /*棋子位置*/  
  1024.   struct killed { struct position data[max_num]; int num;  
  1025.   } *p; /*存储可以吃掉的棋子位置*/  
  1026.   struct stack { struct position node[max_num]; int top;  
  1027.   }; /*栈*/  
  1028.   int w[length][length]; /*棋盘中双方的棋子分布*/  
  1029.   int visited[length][length]; /*给已搜索到的棋子位置作标记,初值为0,搜索到后为1*/  
  1030.  
  1031.   struct killed *kill(int w[length][length],int r,int c,int tag)  
  1032.   { struct killed *p;  
  1033.    struct position *s;  
  1034.    struct stack S;  
  1035.    for (i=0;i<length;i++)  
  1036.    for (j=0;j<length;j++)  
  1037.     (1) ;  
  1038.    S.top=-1; p->num=-1;  
  1039.    if (w[r-1][c]==tag*(-1)) s->row=r-1; s->col=c;  
  1040.    else if (w[r+1][c]==tag*(-1)) s->row=r+1; s->col=c;  
  1041.    else if (w[r][c-1]==tag*(-1)) s->row=r; s->col=c-1;  
  1042.    else if (w[r][c+1]==tag*(-1)) s->row=r; s->col=c+1;  
  1043.    else p->len=0; return p;  
  1044.    push(S,s); visited[s->row][s->col]=1;  
  1045.    flag=search(s,tag);  
  1046.    while ( (2))  
  1047.    { push(S,s); visited[s->row][s->col]=1;  
  1048.     (3);  
  1049.    }  
  1050.    while (S->top>=0)  
  1051.     { pop(S);  
  1052.      (4);  
  1053.      flag=search(s,tag);  
  1054.      while (flag)  
  1055.      { push(S,s);  
  1056.       visit(s);  
  1057.       flag=search(s);  
  1058.      }  
  1059.     }  
  1060.   }  
  1061.  
  1062.   void push( struct stack *S, struct position *s)  
  1063.   { S->top++;  
  1064.    S->node[S->top].row=s->row;  
  1065.    S->node[S->top].col=s->col;  
  1066.    p->num++;  
  1067.    p->data[p->num].row=s->row;  
  1068.    p->data[p->num].col=s->col;  
  1069.   }  
  1070.  
  1071.   void pop(struct stack *S)  
  1072.   { S->top--;  
  1073.   }  
  1074.  
  1075.   struct position *gettop(struct stack *S)  
  1076.   { struct position *s;  
  1077.    s->row=S->data[S->top].row;  
  1078.    s->row=S->data[S->top].row;  
  1079.    return s;  
  1080.   }  
  1081.  
  1082.   int search(struct position *s,int tag)  
  1083.   { int row,col;  
  1084.    row=s->row; col=s->col;  
  1085.    if (W[row+1][col]=(-1)*tag)&&(!visited[row+1][col])  
  1086.    { s->row=row+1;s->col=col; return 1;}  
  1087.    if (W[row-1][col]=(-1)*tag)&&(!visited[row-1][col])  
  1088.    { s->row=row-1;s->col=col; return 1;}  
  1089.    if (W[row][col+1]=(-1)*tag)&&(!visited[row][col+1])  
  1090.    { s->row=row;s->col=col+1; return 1;}  
  1091.    if (W[row][col-1]=(-1)*tag)&&(!visited[row][col-1])  
  1092.    { s->row=row;s->col=col-1; return 1}  
  1093.    (5);  
  1094.   }  
  1095.  
  1096. 答案:  
  1097. (1)strlen(s)+strlen(t) (2)position+strlen(t) (3)target[i]=s[i-strlen(t)]  
  1098. (4)return a (5)return f(a,b-a)  
  1099. (6)q=aveage(head->next)  (7)p->ave=(head->data+q->ave*q->num)/p->num  
  1100. (1)j<d[i] (2)data,d[i],j,n (3)num+i*d<n  (4)data[j+i*d]<temp  (5)data[j]=temp 
  1101. (1)q[rear]=T (2)front<p (3)q[rear]=T->lchild (4)count++ (5)flag<count 
  1102. (1)count (2)(x[i]>end[j])&&(x[i]-start[j]<=1) (3)start[j]=x[i] (4)!flag (5)  
  1103. (1)visited[i][j]=0 (2)flag  (3)flag=search(s,tag) (4)s=gettop(S) (5)return 0