【C語言實現】數據結構算法題及答案


數據結構算法題目集

改天有空再弄一個目錄索引。

  1. 試設計算法,對帶頭結點的單鏈表實現就地逆置,即利用原單鏈表中的結點的存儲單元,將鏈表逆置。
typedef struct LNode
{
    int data;
    struct LNode* next;
}LNode,*LinkList;

void  inverse(LinkList&L)
{
	p = L->next; L->next = NULL; 
	while(p)
    { 
        succ = p->next;    	  //succ指向*p的后繼 
        p->next = L->next; 
        L->next = p;          //*p插入在頭結點之后
        p = succ; 
	}
}

  1. 設計在順序有序表中實現二分查找的算法。
struct record
{
    int key;
    int others;
};

int bisearch(struct record r[],int k)
{
    int low = 0,mid,high = n-1;
    while(low <= high)
    {
        mid = (low+high)/2;
        if(r[mid].key == k)  
            return(mid+1); 
        else if(r[mid].key > k) 
            high = mid-1; 
        else
        	low = mid+1;
    }
    return 0;
}

  1. 設計在單鏈表中刪除值相同的多余結點的算法。
typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *next;
}lklist;

voidd elredundant(lklist*&head)
{
    lklist *p,*q,*s;
    for(p = head;p != 0;p = p->next)
    {
        for(q = p->next,s = q; q != 0)
        	if(q->data == p->data)
            {
                s->next = q->next;
                free(q);
                q = s->next;
            }
        else
        {
            s = q;
            q = q->next;
        }
    }
}

  1. 設計一個求結點 x 在二叉樹中的雙親結點算法。
typedef struct node{
    int data;
    struct node *lchild,*rchild;
}bitree;

bitree *q[20];
int r = 0,f = 0,flag = 0;

void preorder(bitree *bt,char x)
{
    if(bt != 0 && flag == 0)
    if(bt->data == x)
    {
        flag = 1;
        return;
    }
    else
    {
        r = (r+1) % 20;
        q[r] = bt;
        preorder(bt->lchild, x);
        preorder(bt->rchild, x);
    }
}

void parent(bitree *bt,char x)
{
    int i;
    preorder(bt,x);
    for(i = f+1;i <= r; i++)
        if(q[i]->lchild->data == x || q[i]->rchild->data)
            break;
    if(flag == 0)
        printf("not found x\n");
    else if(i <= r)
        printf("%c",bt->data);
    else
        printf("not parent");
}

  1. 設單鏈表中有僅三類字符的數據元素(大寫字母、數字和其它字符),要求利用原單鏈表中結點空間設計出三個單鏈表的算法,使每個單鏈表只包含同類字符。
typedef char datatype;
typedef struct node
{
    datatype data;
    struct node *next;
}lklist;

void split(lklist *head, lklist *&ha, lklist *&hb, lklist *&hc)
{
    lklist *p;
    ha = 0, hb = 0, hc = 0;
    for(p = head; p != 0; p = head)
    {
        head = p->next;
        p->next = 0;
        if(p->data >= 'A' && p->data <= 'Z')
        {
            p->next = ha;
            ha = p;
        }
        else if(p->data >= '0' && p->data <= '9')
        {
            p->next = hb;
            hb = p;
        }
        else
        {
            p->next = hc;
        	hc = p;
        }
    }
}

  1. 設計在鏈式存儲結構上交換二叉樹中所有結點左右子樹的算法。
typedef struct node
{
    int data;
 	struct node *lchild,*rchild;
}bitree;

void swapbitree(bitree*bt)
{
    bitree *p;
    if(bt == 0)
        return;
    swapbitree(bt->lchild);
    swapbitree(bt->rchild);
    p = bt->lchild;
    bt->lchild = bt->rchild;
    bt->rchild = p;
}

  1. 在鏈式存儲結構上建立一棵二叉排序樹。
#define n 10
typedef struct node
{
    int key;
    struct node *lchild,*rchild;
}bitree;

void bstinsert(bitree*&bt,int key)
{
    if(bt == 0)
    {
        bt = (bitree*)malloc(sizeof(bitree));
        bt->key = key;
        bt->lchild = bt->rchild = 0;
    }
    else if(bt->key>key)
        bstinsert(bt->lchild,key);
    else
        bstinsert(bt->rchild,key);
}

void createbsttree(bitree*&bt)
{
    int i;
    for(i = 1;i <= n;i++)
        bstinsert(bt,random(100));
}

  1. 設計判斷兩個二叉樹是否相同的算法。
typedef struct node
{
    datatype data;
    struct node *lchild,*rchild;
}bitree;

int judgebitree(bitree *bt1,bitree *bt2)
{
    if(bt1 == 0 && bt2 == 0)
        return 1;
    else if(bt1 == 0 || bt2 == 0 || bt1->data!=bt2->data)
        return 0;
    else
        return(judgebitree(bt1->lchild,bt2->lchild)*judgebitree(bt1->rchild,bt2->rchild));
}

  1. 設計兩個有序單鏈表的合並排序算法。
void mergelklist(lklist *ha,lklist *hb,lklist *&hc)
{
    lklist *s = hc = 0;
    while(ha != 0 && hb != 0)
    if(ha->data < hb->data)
    {
        if(s == 0)
            hc = s = ha;
        else
        {
            s->next = ha;
            s = ha;
        }
        ha = ha->next;
    }
    else
    {
        if(s == 0)
            hc = s = hb;
        else
        {
            s->next = hb;
            s = hb;
        }
        hb = hb->next;
    }
    if(ha == 0)
        s->next = hb;
    else
        s->next = ha;
}

  1. 設計在鏈式結構上實現簡單選擇排序算法。
void simpleselectsorlklist(lklist *&head)
{
    lklist *p,*q,*s; 
    int min,t;
    if(head == 0 || head->next == 0)
        return;
    for(q = head;q != 0;q = q->next)
    {
        min = q->data;
        s = q;
        for(p = q->next; p != 0;p = p->next)
            if(min > p->data)
            {
                min = p->data;
                s = p;
            }
        if(s != q)
        {
            t = s->data;
            s->data = q->data;
            q->data = t;
        }
    }
}

  1. 設計在順序存儲結構上實現求子串算法。
void substring(char s[],long start,long count,char t[])
{
    long i,j,length = strlen(s);
    if(start<1 || start > length)
        printf("The copy position is wrong");
    else if(start+count-1 > length)
        printf("Too characters to be copied");
    else
    {
        for(i = start-1,j = 0;i < start+count-1;i++,j++)
            t[j] = s[i];
        t[j] = '\0';
	}
}

  1. 設計求結點在二叉排序樹中層次的算法。
int lev=0;
typedef struct node{
    int key;
    struct node *lchild,*rchild;
}bitree;

void level(bitree *bt,int x)
{
    if(bt != 0)
    {
        lev++; 
        if (bt->key == x) 
            return;
        else if(bt->key > x) 
            level(bt->lchild, x); 	
        else
    		level(bt->rchild, x);
}

  1. 設計一個在鏈式存儲結構上統計二叉樹中;的算法。
void countnode(bitree *bt,int &count)
{
    if(bt != 0)
    {
        count++;
        countnode(bt->lchild, count);
        countnode(bt->rchild, count);
    }
}

  1. 設計一個算法將無向圖的鄰接矩陣轉為對應鄰接表的算法。
typedef struct
{
    intvertex[m];
    intedge[m][m];
}gadjmatrix;

typedef struct node1{
    int info;
    int adjvertex;
    struct node1 *nextarc;
}glinklistnode;

typedef struct node2
{
    int vertexinfo;
    glinklistnode *firstarc;
}glinkheadnode;

void adjmatrixtoadjlist(gadjmatrix g1[],glinkheadnode g2[])
{
    inti,j;
    glinklistnode *p;
    for(i = 0;i <= n-1;i++)
        g2[i].firstarc = 0;
    for(i = 0;i <= n-1;i++)
        for(j = 0;j <= n-1;j++)
    		if(g1.edge[i][j] == 1)
                {
                    p = (glinklistnode*)malloc(sizeof(glinklistnode));
                    p->adjvertex = j;
                    p->nextarc = g[i].firstarc;
                    g[i].firstarc = p;
                    p = (glinklistnode*)malloc(sizeof(glinklistnode));
                    p->adjvertex = i;
                    p->nextarc = g[j].firstarc;
                    g[j].firstarc = p;
                }
}

  1. 設計計算二叉樹中所有結點值之和的算法。
void sum(bitree *bt,int &s)
{
	if(bt != 0)
    {
        s = s + bt->data;
        sum(bt->lchild,s);
        sum(bt->rchild,s);
    }
}

  1. 設計將所有奇數移到所有偶數之前的算法。
void quickpass(int r[],ints,int t)
{
    int i = s,j = t,x = r[s];
    while(i<j)
    {
        while(i<j && r[j]%2 == 0)
            j = j-1; 
        if(i<j)
        {
            r[i] = r[j];
            i = i+1;
        }
        while(i<j && r[i]%2 == 1)
            i = i+1; 
        if(i<j)
        {
            r[j] = r[i];
            j = j-1;
        }
    }
    r[i] = x;
}

  1. 設計判斷單鏈表中元素是否是遞增的算法。
int isriselk(lklist *head)
{
    if(head == 0||head->next == 0)
        return 1;
    else
    	for(q = head,p = head->next; p! = 0; q = p, p = p->next)
            if(q->data > p->data)
                return 0;
    return 1;
}

  1. 設計在鏈式存儲結構上合並排序的算法。
void mergeLinkList(LinkList *ha,LinkList *hb,LinkList *&hc)
{
    LinkList *s = hc = 0;
    while(ha! = 0 && hb! = 0)
    {
         if(ha->data < hb->data)
         {
             if(s == 0)
                 hc = s = ha;
             else
             {
                 s->next = ha;
                 s = ha;
             };
             ha = ha->next;
         }
        else
        {
            if(s == 0)
                hc = s = hb;
            else
            {
                s->next = hb;
                s = hb;
            };
            hb = hb->next;
        }
        if(ha == 0)
            s->next = hb;
        else
            s->next = ha; 
    }
}
  1. 設計在二叉排序樹上查找結點 X 的算法。
BiTree *bstsearch1(BiTree *t,int key)
{
    BiTree *p = t;
    while(p! = 0)
    {
        if (p->key == key) 
            return(p);
    	else if (p->key > key)
            p = p->lchild; 
    	else
    		p = p->rchild;
      }
    return 0;
}

  1. 設關鍵字序列 ( K1、K2、...、Kn-1 ) 是堆,設計算法將關鍵字序列 ( K1、K2、...、Kn-1、X ) 調整為堆。
void adjustheap(int r[],int n)
{
    intj = n,i = j/2,temp = r[j-1];
    while(i> = 1)
        if(temp> = r[i-1])
            break;
    	else
        {
            r[j-1] = r[i-1];
            j = i;
            i = i/2;
        }
    r[j-1] = temp;
}

  1. 設計一個算法,求一個帶頭結點的單鏈表中的結點個數。
int CountNodes(LinkList&L) 
{
    int count=0;
    LinkList p; 
    p = L->next;
    while(p){ 
    count++; 
    p = p->next; 
    }
    return count; 
}

  1. .已知兩個非空的帶有頭結點的單鏈表 La 和 Lb,且 L 和 La和 Lb的元素按值非遞減排列(即元素按值遞增有序),試設計算法將該兩個有序鏈表合並為一個有序鏈表。
void MergeList(LinkList &LA,LinkList &LA,LinkList &LC)
{
    pa = LA->next;
    pb = LB->next;
    LC = pC = LA;
    while(pa&&pb){
    if(pa->data< = pb->data)(
    pc->next = pa;pc = pa;pa = pa->next;
    else{pc->next = pb;pc = pb;pb = pb->next;}
    pc->next = pa ? pa:pb;
    free(LB);
}


  1. 設計判斷二叉樹是否為二叉排序樹的算法。
int minnum = -32768,flag = 1;
typedef struct node
{
    int key;
    struct node *lchild,*rchild;
}bitree;

void inorder(bitree*bt)
{
    if (bt != 0)
    {
        inorder(bt->lchild); 
        if(minnum > bt->key)
            flag = 0;
    	minnum = bt->key;
        inorder(bt->rchild);
    }
}

  1. 在鏈式存儲結構上設計直接插入排序算法。
void straightinsertsort(lklist *&head)
{
    lklist *s,*p,*q; 
    int t;
    if(head == 0||head->next == 0)
        return;
    else
        for(q = head, p = head->next; p! = 0; p = q->next)
        {
            for(s = head; s != q->next; s = s->next)
                if(s->data > p->data)
                    break;
            if(s == q->next)
                q = p;
             else
             {
                 q->next = p->next; 
                 p->next = s->next; 
                 s->next = p;
                 t = p->data;
                 p->data = s->data;
                 s->data = t;
             }
        }
}

  1. 設有一組初始記錄關鍵字序列 ( K1、K2、...、Kn ),要求設計一個算法能夠在 O(n) 的時間復雜度內將線性表划分成兩部分,其中左半部分的每個關鍵字均小於 Ki,右半部分的每
    個關鍵字均大於等於 Ki
void quickpass(int r[],int s,int t)
{
    int i = s, j = t, x = r[s];
    while(i<j)
    {
        while(i<j && r[j]>x)
            j = j-1;
        if(i<j)
        {
            r[i] = r[j];
            i = i+1;
        }
        while(i<j && r[i]<x)
            i = i+1;
        if(i<j)
        {
            r[j] = r[i];
            j = j-1;
        }
    }
    r[i] = x;
}

  1. 設有兩個集合 A和集合 B,要求設計生成集合 C=A∩B 的算法,其中集合 A、B和 C 用
    鏈式存儲結構表示。
typedef struct node
{
    int data;
    struct node *next;
}lklist;

void intersection(lklist *ha,lklist *hb,lklist *&hc)
{
    lklist *p,*q,*t;
    for(p = ha, hc = 0; p != 0;p = p->next)
    {
        for(q = hb; q!=0; q = q->next)
            if(q->data == p->data)
                break;
    	if(q != 0)
        {
            t = (lklist*)malloc(sizeof(lklist));
            t->data = p->data;
            t->next = hc;
            hc = t;
        }
    }
}

  1. 假設二叉樹采用二叉鏈存儲結構存儲,設計一個算法,求出根結點到給定某結點之間的路徑。
typedef struct BiTNode{ 
     int data;                  // 數據域  
     struct BiTNode *lchild,*rchild;   // 左、右;指針  
}BTNode,*BiTree; 

#define MaxSize 100 
int AncestoPath(BTNode *b, BTNode *s)
{ 
    BTNode* st[MaxSize]; 
    BTNode *p; 
    int i,flag,top = -1; 
    do{ 
        while(b != NULL){ 
            st[++top]=b; 
            b = b->lchild; 
        } 
        p = NULL;                        //p 指向當前結點的前一個已訪問結點  
        flag = 1;                          // 設置 b 的訪問標記為已訪問  
        while(top!=-1 && flag){ 
            b = st[top];                  // 取出棧頂元素  
            if(b->rchild == p){           // 右子樹不存在或已被訪問,訪問之  
                if(b == s){               // 找到目標結點,輸出路徑  
                    for(i = 0; i <= top; ++i) 
                        printf("%c", st[i]->data); 
                    return 1; 
                } 
                else
                { 
                    top--; 
                    p=b;                 //p 指向剛才訪問的結點  
                } 
            } 
            else
            { 
                b=b->rchild;            //b 指向右子樹  
                flag=0;                 //設置未被訪問標記  
            } 
        } 
    }while(top != -1);                 //棧不空時循環  
    return 0;                          //其他情況返回 0 
} 

  1. 將一個數組最開始的若干個元素搬到數組的末尾,稱之為數組的旋轉。輸入一個已排好序數組的一個旋轉,求該旋轉數組的最小元素。如,數組 {3, 4, 5, 1, 2} 為有序數組{1, 2, 3, 4, 5}的一個旋轉數組,該數組的最小值為1。
int Min(int *numbers,int length)
{           
    if(numbers == 0 || length <= 0) 
        return 0; 
    int index1 = 0;                          // 第一個指針  
    int index2 = length-1;                   // 第二個指針  
    int indexMid = index1;                   // 中間指針  
    while(numbers[index1]> = numbers[index2])
    { 
        if(index2-index1 == 1)
        { 
            indexMid = index2; 
            break; 
        } 
        indexMid = (index1+index2)/2; 
        if(numbers[indexMid] >= numbers[index1])   //在右區間  
            index1 = indexMid; 
        else if(numbers[indexMid] <= numbers[index2])  //在左區間  
            index2 = indexMid; 
    } 
    return numbers[indexMid]; 
}

  1. 假設二叉樹采用二叉鏈表存儲結構存儲,設計一個算法,求先序遍歷序列中第k (1 ≤ k ≤ 二叉樹中結點個數)個結點的值。
typedef struct BiTNode{ 
     int data;                      // 數據域  
     struct BiTNode  *lchild,*rchild;   // 左、右;指針  
}BTNode,*BiTree; 

int n = 1; 
//遞歸實現
int PreNode(BTNode *b,int k)
{ 
        int ch; 
        if(b == NULL) 
             return '#'; 
        if(n == k) 
             return b->data; 
        ++n; 
        ch = PreNode(b->lchild,k); 
        if(ch ! =  '#') 
             return ch; 
        ch = PreNode(b->rchild,k); 
        return ch; 
} 

//非遞歸實現
#define MaxSize 100 
int n = 1; 
int PreNode(BTNode *b,int k)
{ 
    BTNode *st[MaxSize],*p; 
    if(b !=  NULL)
    { 
        st[++top] = b; 
        while(top>-1)
        { 
            p = st[top--]; 
            ++n; 
            if(n == k)
                return p->data; 
            if(p->rchild)
                st[++top] = p->rchild;  // 右子樹進棧  
            if(p->lchild)
                st[++top] = p->lchild;  // 左子樹進棧  
        } 
    } 
    return ''; 
} 

  1. 在數組中,某個數字減去它右邊的數字得到一個數對之差。求所有數對之差的最大值。例如,在數組 {2, 4, 1, 16, 7, 5, 11, 9} 中,數對之差的最大值是 11,是 16 減去 5 的結果。
//解法一
int MaxDiff_Solution1(int numbers[], unsigned length) 
{ 
    if(numbers == NULL || length<2) 
        return 0; 
    int max,min; 
    return 
	MaxDiffCore(numbers,numbers+length-1, &max, &min); 
} 

int MaxDiffCore(int* start,int* end,int* max,int* min) 
{ 
    if(end == start) 
    { 
        *max = *min = *start; 
        return 0; 
    } 
    int* middle = start+(end-start)/2; 
    int maxLeft, minLeft; 
    int leftDiff = MaxDiffCore(start,middle,&maxLeft,&minLeft); 
    int maxRight, minRight; 
    int rightDiff = MaxDiffCore(middle+1,end,&maxRight,&minRight); 
    int crossDiff = maxLeft-minRight; 
    *max = (maxLeft>maxRight)? maxLeft:maxRight; 
    *min = (minLeft<minRight)? minLeft:minRight; 
    int maxDiff = (leftDiff>rightDiff)? leftDiff:rightDiff; 
    maxDiff = (maxDiff>crossDiff)? maxDiff:crossDiff; 
    return maxDiff; 
} 

//解法二
int MaxDiff_Solution2(int numbers[],unsigned length) 
{ 
    if(numbers == NULL||length<2) 
        return 0; 
    int max = numbers[0];                 // 第i個數之前的最大值  
    int maxDiff = max-numbers[1];         // maxDiff 表 示diff[i-1] 
    for(int i = 2; i<length; ++i) 
    { 
        if(numbers[i-1] > max)             // 第i 個數和之前的最大值比較  
            max = numbers[i-1]; 
        int currentDiff = max-numbers[i];  //currentDiff 表示diff[i] 
        if(currentDiff > maxDiff) 
            maxDiff = currentDiff; 
    } 
    return maxDiff; 
} 

  1. 假設二叉樹采用二叉鏈表存儲結構,設計一個算法求其指定的某一層 k(k>1)的葉子結點個數。
//解法一
typedef struct BiTNode{ 
     ElemType data;                      // 數據域  
     struct BiTNode  *lchild,*rchild;   // 左、右;指針  
}BTNode,*BiTree; 

#define MaxSize 100          // 設置隊列的最大容量  
int LeafKLevel(BTNode *root,int k)
{ 
    BTNode* q[MaxSize];          // 聲明隊列, end1 為頭指針, end2為尾指針  
    int end1, end2, sum=0;       // 隊列最多容納 MaxSize-1 個元素  
    end1 = end2 = 0;             // 頭指針指向隊頭元素,尾指針指向隊尾的后一個元素  
    int deep = 0;                // 初始化深度       
    BTNode *lastNode;            // lastNode 用來記錄當前層的最后一個結點  
    BTNode *newlastNode;         // newlastNode 用來記錄下一層的最后一個結點  
    lastNode = root;             //lastNode 初始化為根節點  
    newlastNode = NULL;          //newlastNode 初始化為空  
    q[end2++] = root;            // 根節點入隊  
    while(end1 != end2)
    {                            // 層次遍歷,若隊列不空則循環  
         BTNode *t = q[end1++];      // 拿出隊列中的頭一個元素  
         if(k==deep)
         {                // 找到特定層,統計葉子結點個數  
             while(end1 != end2)
             { 
                 t = q[end1++]; 
                 if(t->lchild == NULL && t->rchild == NULL) 
                     ++sum; 
             } 
             break; 
        } 
         else
         {                       // 沒到特定層,層次遍歷  
             if(t->lchild != NULL)
             {  // 若非葉子結點把左結點入隊  
                 q[end2++] = t->lchild;  
                 newlastNode = t->lchild; 
             }                   // 並設下一層的最后一個結點為該結點的左結點  
             if(t->rchild != NULL)
             {	 // 處理葉節點  
                 q[end2++] = t->rchild; 
                 newlastNode = t->rchild; 
              } 
             if(t == lastNode)
             {    
                 // 若該結點為本層最后一個結點,更新lastNode 
                 lastNode = newlastNode; 
                 deep += 1;          // 層數加 1 
             } 
         } 
     } 
    return sum;                  // 返回葉子結點個數  
} 


//解法二
int n; 
int LeafKLevel(BiTree root, int k)
{ 
    n=0; 
    PreOrder(root, 0, k); 
    return 0; 
} 

int PreOrder(BiTree root, int deep, int k)
{ 
    if(deep<k)
    { 
 		if(root->lchild != NULL)     //若左子樹不空,對左子樹遞歸遍歷  
     		PreOrder(root->lchild, deep+1); 
 		if(root->rchild != NULL)     //若右子樹不空,對右子樹遞歸遍歷  
     		PreOrder(root->rchild, deep+1); 
	} 
	else if(deep == k && root->lchild == NULL && root->rchild == NULL) 
 		++n; 
} 

  1. 設有 n 個不全為負的整型元素存儲在一維數組 A[n]中,它包含很多連續的子數組,例如數組 A={1,-2,3,10,-4,7,2,-5 },請設計一個時間上盡可能高效的算法,求出數組 A 的子數組之和的最大值 (例如數組 A 的最大的子數組為 { 3,10,-4,7,2 },因此輸出為該子數組的和 18)。
int MaxSum(int n,int *a){ 
    int sum=0,b=0; 
    for(int i=1;i<=n;i++){ 
        if(b>0) b+=a[i]; 
        else b=a[i]; 
        if(b>sum) sum=b; 
    } 
    return sum; 
} 

  1. 編寫算法判斷該二叉樹是否是平衡二叉樹,即二叉樹中任意結點的左右子樹的深度相差不超過 1。
void Judge_AVL(BiTree bt,int &balance,int &h)
{ 
    int bl,br,hl,hr;           // 左、右子樹的平衡標記和高度  
    if(bt == NULL)
    {          				  // 空樹,高度為 0 
        h = 0; 
        balance = 1; 
    } 
    else if(p->lchild == NULL && p->rchild == NULL)
    { 
        // 僅有根結點,則高度為 1 
        h = 1; 
        balance = 1; 
    } 
    else
    { 
        Judge_AVL(bt->lchild,bl,hl);   // 遞歸判斷左子樹  
        Judge_AVL(bt->rchild,br,hr);   // 遞歸判斷右子樹  
        h = (hl>hr ? hl : hr)+1; 
        if(abs(hl,hr) < 2)        // 若高度絕對值小於 2 ,則看左、右子樹是否都平衡  
            balance = bl & br;      // &為邏輯與,即左、右子樹都平衡時,二叉樹平衡  
        else 
            balance = 0; 
    } 
} 

  1. 單鏈表有環,是指單鏈表的最后一個結點的指針指向了鏈表中的某個結點(通常單鏈表的最后一個結點的指針域是為空的)。試編寫算法判斷單鏈表是否存在環。
bool IsExitsLoop(list *head) 
{ 
    list *slow = head, *fast = head;           // 定義兩個指針  
    while(fast && fast->next)             // 都不空  
    { 
        slow = slow->next; 
        fast = fast->next->next; 
        if(slow == fast)                  // 相遇,存在環  
            break; 
    } 
    return !(fast == NULL || fast->next == NULL); 
} 

  1. 已知線性表(a 1 , a 2 , a 3 ,…,a n)存放在一維數組 A 中。試設計一個在時間和空
    間兩方面都盡可能高效的算法,將所有奇數號元素移到所有偶數號元素前,並且不得
    改變奇數號(或偶數號)元素之間的相對順序。
void Bubble_Swap(int A[],int n)
{ 
    int i = n,v = 1;   // i 為工作指針,初始假設 n 為奇數, v 為“塊”的大小 
    int temp;          // 輔助變量  
    if( n%2 == 0) 
        i = n-1;       // 若 n 為偶數,則令 i 為 n-1 
    while(i>1)
    {             			 // 假設數組從 1 開始存放。當 i = 1 時,氣泡浮出水面  
        temp = A[i-1];         // 將“塊”前的偶數號元素暫存  
        for(int j = 0; j<v; j++) // 將大小為 v 的“塊”整體向前平移  
            A[i-1+j] = A[i+j];   // 從前往后依次向前平移  
        A[i+v-1] = temp;       // 暫存的奇數號元素復制到平移后空出的位置  
        i = i-2;
        v++;           // 指針向前,塊大小增 1 
    }
} 

  1. 已知長度為 n(n>1)的單鏈表,表頭指針為 L,判斷該單鏈表是否中心對稱。
typedef struct LNode{                         
    char data;                              // 結點數據  
    struct LNode *next;                     // 結點鏈接指針  
} *LinkList; 

int Str_Sym(LinkList L,int n)
{  
    Stack s;
    initstack(s);                   		 // 初始化棧  
    LNode *q,*p = L->next;                     //q 指向出棧元素,p 工作指針  
    for(int i = 1;i <= n/2;i++)
    {                 // 前一半結點入棧  
        push(p); 
        p = p->next; 
	} 
	if( n%2 == 1) p = p->next;                   // 若 n 為奇數,需要特殊處理  
	while(p != null){                         // 后一半表依次和前一半表比較  
    	q = pop(s);                           // 出棧一個結點  
    	if(q->data == p->data) p = p->next;     // 相等則繼續比較下一個結點  
    else 
        break;                             // 不等則跳出循環  
    } 
    if(empty(s)) 
        return 1;                  // 棧空,則說明對稱  
    else 
        return 0;                          // 否則不對稱  
} 


  1. 現要求設計一個時間復雜度盡可能高效的算法,對於鏈表中 data 的絕對值相等的結點,僅保留第一次出現的結點而刪除其余絕對值相等的結點。
typedef struct node {
	int  data;
	struct node *link;
}
NODE;
Typedef NODE *PNODE;
void func (PNODE h,int n) {
	PNODE p = h,r;
	int *q,m;
	q = (int *)malloc(sizeof(int)*(n+1));
	//申請 n+1個位置的輔助空間 
	for (int i = 0;i<n+1;i++)     //數組元素初值置 0 
	*(q+i) = 0;
	while(p->link! = NULL) 
    {
		m = p->link->data > 0 ? p->link->data : -p->link->data;
		if( *(q+m) == 0)          //判斷該結點的 data是否已出現過 
        {
			*(q+m) = 1;
			//首次出現 
			p = p->link;
			//保留
		} 
    	else                      //重復出現 
    	{
			r = p->link;
			//刪除 
			p->link = r->link 
			free(r);
		}
	}
	free(q);
}

  1. 設 root 為指向 T 的根結點的指針,請設計求 T 的 WPL 的算法。
typedef struct BiTNode
{ 
	int weight; 
	struct BiTNode *lchild,*rchild; 
}BiTNode,*BiTree; 

int WPL(BiTree root)
{ 
	return wpl_PreOrder(root, 0); 
} 

int wpl_PreOrder(BiTree root, int deep)
{ 
	static int wpl = 0;                 //定義一個 static變量存儲 wpl 
	if(root->lchild == NULL && root->lchild == NULL)  //若為葉子結點,累積 wpl 
		wpl += deep * root->weight; 
	if(root->lchild != NULL)           //若左子樹不空,對左子樹遞歸遍歷 
		wpl_PreOrder(root->lchild, deep+1); 
	if(root->rchild != NULL)           //若右子樹不空,對右子樹遞歸遍歷 
		wpl_PreOrder(root->rchild, deep+1); 
	return wpl; 
} 

  1. 已知一個整數序列 A=(A0 , A1 , …, An+1 ),其中 0 ≤ Ai <n(0 ≤ i<n)。若存在 Ap1 = Ap2 =…= Apm = x 且 m> n/2 (0 ≤ pk <n,1 ≤ k ≤m),則稱 x 為 A 的主元素。例如 A=(0, 5, 5, 3, 5, 7, 5, 5),則 5 為主元素;又如 A=(0, 5, 5, 3, 5, 1, 5, 7),則 A 中沒有主元素。假設 A 中的 n 個元素保存在一個一維數組中,請設計一個盡可能高效的算法,找出 A 的主元素。若存在主元素,則輸出該元素;否則輸出-1。
int Majority(int A[],int n) 
{ 
    int i,c,count = 1;                 //c用來保存候選主元素,count用來計數 
    c = A[0];                          //設置 A[0]為候選主元素 
    for(i = 1; i<n; i++)                 //查找候選主元素 
        if(A[i] == c) 
            count++;             	//對 A中的候選主元素計數 
    	else 
        	if(count>0)             //處理不是候選主元素的情況 
            	count--; 
            else                 	//更換候選主元素,重新計數 
            {   
                c = A[i]; 
             	count = 1; 
            } 
    if(count>0) 
        for(i = count = 0; i<n; i++)  	//統計候選主元素的實際出現次數 
            if(A[i] == c) 
                count++; 
    if(count>n/2) 
        return c;          			//確認候選主元素 
    else 
        return -1;                  //不存在主元素 
} 

  1. 設 str1 和 str2 分別指向兩個單詞所在單鏈表的頭結點,鏈表結點結構為 ,請設計一個時間上盡可能高效的算法,找出由 str1 和 str2 所指向兩個鏈表共同后綴的起始位置。
LinkNode *Find_1st_Common(LinkList str1,LinkList str2)
{ 
    int len1 = Length(str1),len2 = Length(str2); 
    LinkNode *p,*q; 
    for(p = str1;len1>len2;len1--)             //使 p指向的鏈表與 q指向的鏈表等長 
         p = p->next; 
    for(q = str2;len1<len2;len2--)             //使 q指向的鏈表與 p指向的鏈表等長 
         q = q->next; 
    while(p->next != NULL&&p->next != q->next)
    {  
        //查找共同后綴起始點 
         p = p->next;                          //兩個指針同步向后移動 
         q = q->next; 
    } 
	return p->next;                             //返回共同后綴的起始點 
} 

  1. 一個長度為 L(L≥1)的升序序列 S,處在第 L/2 個位置的數稱為 S 的中位數。例如,若序列 S1=(11,13,15,17,19),則 S1 的中位數是 15,兩個序列的中位數是含它們所有元素的升序序列的中位數。例如,若 S2=(2,4,6,8,20),則 S1 和 S2 的中位數是 11。現在有兩個等長升序序列 A 和 B,試設計一個在時間和空間兩方面都盡可能高效的算法,找出兩個序列 A 和 B 的中位數。
int M_Search(int A[],int B[],int n)
{ 
    int s1 = 0,d1 = n-1,m1,s2 = 1,d2 = n-1,m2; 
    //分別表示序列 A和 B的首位數、末位數和中位數 
    while(s1 != d1||s2 != d2)
    { 
        m1 = (s1+d1)/2; 
        m2 = (s2+d2)/2; 
          if(A[m1] == B[m2]) 
            return A[m1];          //滿足條件 1) 
        if(A[m1] < B[m2])
        {          					//滿足條件 2) 
            if((s1+d1)%2 == 0)
            {      					//若元素個數為奇數 
                s1 = m1;             //舍棄 A中間點以前的部分,且保留中間點 
                d2 = m2;             //舍棄 B中間點以后的部分,且保留中間點 
            } 
            else
            {                 		 //元素個數為偶數 
                s1 = m1+1;           //舍棄 A中間點及中間點以前部分 
                d2 = m2;             //舍棄 B中間點以后部分且保留中間點 
            } 
        } 
        else
        {                      		//滿足條件 3) 
            if( (s1+d1)%2 == 0)
            {    					//若元素個數為奇數 
                d1 = m1;             //舍棄 A中間點以后的部分,且保留中間點 
                s2 = m2;             //舍棄 B中間點以前的部分,且保留中間點 
            } 
            else
            {                         //元素個數為偶數 
                d1 = m1+1;            //舍棄 A中間點以后部分,且保留中間點 
                s2 = m2;             //舍棄 B中間點及中間點以前部分 
            } 
        } 
    } 
    return A[s1]<B[s2] ? A[s1]:B[s2]; 
} 

  1. 設將 n(n>1)個整數存放到一維數組 R 中。試設計一個在時間和空間兩方面都盡可能高效的算法。將 R 中保存的序列循環左移 p(0<p<n)個位置。
void Reverse(int R[],int from,int to)
{ 
    int i,temp; 
    for(i = 0; i< (to-from+1)/2; i++) 
    {    
        temp = R[from+i];
        R[from+i] = R[to-i];
        R[to-i] = temp;
    } 
}

void Converse(int R[],int n,int p)
{ 
    Reverse(R,0,p-1); 
    Reverse(R,p,n-1); 
    Reverse(R,0,n-1); 
} 

  1. 查找鏈表中倒數第 k 個位置上的結點(k 為正整數)。若查找成功,算法輸出該結點的 data 域的值,並返回 1;否則,只返回 0。
typedef int ElemType;                       //鏈表數據的類型定義 
typedef struct LNode
{                       					//鏈表結點的結構定義 
    ElemType  data;                      	//結點數據 
    struct Lnode *link;                     //結點鏈接指針 
} *LinkList; 

int  Search_k(LinkList list,int k)
{ 
    //查找鏈表 list倒數第 k個結點,並輸出該結點 data域的值 
    LinkList p = list->link,q = list->link;     //指針 p、q指示第一個結點 
    int count = 0; 
    while(p != NULL)
    {                         				//遍歷鏈表直到最后一個結點 
        if(count<k) 
            count++;                		//計數,若 count<k只移動 p 
        else q = q->link;p = p->link;       //之后讓 p、q同步移動 
    } 
    if(count<k) 
        return  0;                          //查找失敗返回 0 
    else 
    {                                  		//否則打印並返回 1 
        printf("%d",q->data); 
        return  1; 
    } 
} 

  1. 已知二叉樹用二叉鏈表方式存在,編寫算法,統計二叉樹中的葉子結點數目並輸出所有的葉子結點。


  1. 已知無向圖采用鄰接表結構存儲,要求按深度優先搜索策略統計連通子圖的個數,並輸出所有連通子圖的生成樹。(生成樹中的邊用 vi , vj )格式輸出)


  1. 已知樹,采用;—兄弟表示法存儲,編寫算法,按(雙親、;)格式輸出樹中的邊。


  1. 已知二叉樹采用二叉鏈表方式存放。請統計二叉樹中度為 1 的結點數目,輸出二叉樹中所有的葉子結點。


  1. 已知樹采用;—兄弟的二叉鏈表存儲,編寫算法,按層次輸出樹中所有結點。


  1. 鍵盤輸入 N 個值,編寫算法要求按照輸入順序依次建立鏈表中各個結點。


  1. 已知二叉樹采用二叉鏈表存放,要求編寫算法不用遞歸也不用棧,返回二叉樹T的后序序列中的第一個結點的指針。


  1. 編寫算法,為依次輸入的 n 個元素構造哈希表,H(x) 為哈希函數,以線性探測再散列解決沖突。


  1. 已知無向圖采用鄰接表結構存儲,要求按廣度優先搜索策略統計連通子圖的個數,並輸出所有連通子圖的生成樹。(生成樹中的邊用 vi , vj )格式輸出)


  1. 鍵盤輸入一組非零的整數序列,最后輸入 0 為結束標志,要求根據輸入建立一棵二叉排序樹算法,采用二叉鏈表存放。


  1. 給出按由大到小順序輸出此二叉排序樹中結點值的算法。


  1. 已知二叉樹采用二叉鏈表結構存放,要求統計二叉樹中度為 1 結點個數和度為 2 的結點個數。


  1. 建立一棵二叉樹,要求以二叉鏈表存儲結構存儲。


  1. 已知有N個結點的無向圖,采用鄰接表結構存儲,要求由根開始逐層輸出連通子圖中所有生成樹中的各條邊,邊輸出格式為 ( Ki ,Kj ) 。


  1. 鍵盤輸入 n 個有序值建立線性表,按折半查找策略實習查找給定值為 key 的元素。


  1. 編寫二分查找的遞歸算法。


  1. 編寫算法,對一棵以;—兄弟鏈表表示的樹統計其葉子結點的個數。


  1. 已知 A=(a1, a2, …, am),B=(b1, b2, …, bn)均為順序表,試編寫一個比較 A¸B 大小的算法。
int compare(SqList La, SqList Lb) 
{
    i = 0;
    while (i<La.Length && i<Lb.Length) 
    {
        if (La.elem[i] == Lb.elem[i])    
            i++;
        else if (La.elem[i]<Lb.elem[i])
        	return -1;
        else 
            return 1;
    }
    if ( i>La.length && i>Lb.Length)    
        return 0;
    else if (i>Lb.Length)
        return 1;
    else  
        return -1;
}

  1. 刪除有序表中所有其值大於 mink 且小於 maxk 的數據元素。
void delete(LinkList &L, int mink, int maxk) 
{
    p = L->next;
    while (p && p->data <= mink)
    { 
        pre = p;    
        p = p->next; 
    } //查找第一個值>mink 的結點
    if (p) 
    {
        while (p && p->data<maxk)    
            p = p->next;       //查找第一個值≥maxk 的結點 
        q = pre->next;
        pre->next = p;    	//修改指針
        while (q != p) 
        { 
            s = q->next; 
            delete q;
            q = s; 
        } // 釋放結點空間
    } 
}

  1. 逆置線性鏈表
void  inverse(LinkList &L) 
{
    // 逆置帶頭結點的單鏈表  L
    p = L->next;    
    L->next = NULL;
    while(p)
    {
        succ = p->next;        	// succ 指向*p 的后繼
        p->next = L->next;
        L->next = p;              // *p 插入在頭結點之后
        p  =  succ;
    }
}

  1. 已知數組 A[1..n]的元素類型為整型 int,設計一個時間和空間上盡可能高效的算
    法,將其調整為左右兩部分,左邊所有元素為奇數,右邊所有元素為偶數。
void Adjust(int A[])
{
    //調整數組 A,使得 A 的左邊為奇數,右邊為偶數
    int i = 1,j = n,temp;
    while(i != j)
    {
        while(A[i]%2 != 0) 
            i++;      			//A[i]為奇數時,i 增 1
        while(A[j]%2 == 0) 
            j++;   				//A[j]為偶數時,j 減 1
        if (i<j) 			    //A[i]為偶數、A[j]為奇數時,交換
        {
            temp=A[i];
            A[i]=A[j];
            A[j]=temp; 
        }
       
    }
}

  1. 括號匹配的檢驗
void match(char *exp)
{
    initStack(s);
    char c; 
    int i = 0, b = 1; 
    while(exp[i] != '\0' && b == 1)
    {
        if (exp[i] == '(') 
            push(S,exp[i]);
        else if (exp[i] == ')')
        {
            c = Pop(S); 
            if (c != '(') 
                b = 0;
    	}
    	i++;
    }
    return (b&&StackEmpty(S));
}

  1. 識別讀入的一個字符序列是否為反對稱的字符序列。
int symmetry(char Ch[] ) 
{
    //若Ch[] 為反對稱字符序列,則返回1,否則返回0。
    p = Ch;    
    InitStack(S);
    while (*p!='&') 
    { 
        Push(S,*p);
        p++; 
    }
    state = 1;
    p++;      // 濾去字符‘&’
    while (*p!='@' && state ) 
    {
    	if (NOT StackEmpty(S)&&GetTop(S)==*p )
        { 
            Pop(S,e);
            p++; 
        }
        else 
            state = 0;
    }
    return(StackEmpty(S) && state )
}

  1. 判別讀入的字符序列是否為“回文”。
Status ex()    
{
    // 若從終端依次輸入的字符序列是“回文”,
    // 則返回 TRUE,否則返回 FALSE
    InitStack(S);    
    InitQueue(Q); 
    scanf(ch);
    while(ch!=@) 
    {
        Push(S, ch);
        EnQueue(Q, ch);
        scanf(ch);
     }
    state=TRUE;
    while(!StackEmpty && state) 
    {
        if(GetTop(S)==GetHead(Q))
        { 
            Pop(S);
            DeQueue(Q);
        }
        else 
            state=FALSE;
    }
    return state;
}

  1. 中序遍歷非遞歸算法
void NRInOrder(BiTree bt)
{
    BiTree Stack[MAX_TREE_SIZE],p;
    int top = 0; 
    p = bt;
    if (bt == NULL) 
        return;
    while(!(p == NULL && top == 0)) 
    {   
        while(p != NULL) 
        { 
            if(top < MAX_TREE_SIZE-1) //將當前指針 p 壓棧
            	Stack[top++] = p;
            else
            { 
                printf("棧溢出"); 
                return;
            }
        	p = p->lchild;      		//指針指向 p 的左;結點
        }
        if (top <= 0) 
            return;    //棧空時結束
        else
        { 
            p = Stack[--top];          //從棧中彈出棧頂元素
            Visit(p->data);          //訪問結點的數據域
            p = p->rchild;     //指針指向 p 的右;結點
      	}
   }
}

  1. 先序非遞歸算法
void PreOrder1(BiTree b)
{
    BiTree St[MAX_TREE_SIZE],p;
    int top = -1;
    if (b != NULL) 
    {
        St[++top] = b;           	  //根結點進棧
        while (top>-1)
        {    					 	  //棧不空時循環
            p = St[top--];            //出棧並訪問該結點
            Visit(p->data);   
            if (p->rchild != NULL)    //右;結點進棧
                St[++top] =  p->rchild;
            if (p->lchild != NULL)    //左;結點進棧
                St[++top] =  p->lchild;
        }
  	}
}

  1. 后序遍歷非遞歸算法
void PostOrder1(BiTree b)
{
    BiTree St[MAX_TREE_SIZE],p;
    int flag,top = -1;
    if (b != NULL)
    {
	   do{
            while(b != NULL) 
            {    //掃描*b 的左結點並進棧
                St[++top] = b;
                b = b->lchild;
            }
            p = NULL;    // p 指向棧頂結點的前一個已訪問的結點
            flag = 1;    // 設置 b 的已訪問標記為已訪問過
            while(top != -1 &&flag)
            {
                b = St[top];                  //取出當前的棧頂元素
                if (b->rchild == p)
                {   
                    //右;不存在或右;已被訪問,則訪問*b
                    Visit(b->data); 		//訪問*b 結點
                    top--;
                    p = b;                  	//p 指向被訪問的結點
                }
                else
                {
                    b = b->rchild;  //b 指向右;結點
                    flag = 0;              //設置未被訪問的標記
                }
            }
		}while(top! = -1);
	}
}

  1. 查詢二叉樹中某個結點
Status Preorder (BiTree T, ElemType x, BiTree &p) {
    // 若二叉樹中存在和 x 相同的元素,
    //則 p 指向該結點並返回  OK,否則返回  FALSE   
    if(T) 
    {
        if(T->data == x) 
        { 
            p = T; 
            return OK;
        } 
        else 
        {
            if(Preorder(T->lchild, x, p)
                return OK;
            else 
                return(Preorder(T->rchild, x, p)) ;
        }
    }//if 
    else 
       return FALSE;
}

  1. 求二叉樹的深度
int Depth (BiTree T )
{	
    //  返回二叉樹的深度
    if ( !T ) 
        depthval = 0;
    else 
    {
        depthLeft = Depth( T->lchild );
        depthRight= Depth( T->rchild );
        depthval = 1+ (depthLeft>depthRight ? 
                depthLeft:depthRight);
    }
    return depthval;
}

  1. 復制二叉樹
BiTree GetTreeNode(TElemType item,BiTNode *lptr , BiTNode *rptr)
{
    if (!(T = new BiTNode))
    	exit(1);
    T-> data = item;
    T-> lchild = lptr;        
    T-> rchild = rptr;
    return T;
}

BiTree CopyTree(BiTNode *T) 
{ 
    if (!T )        
        return NULL;
    if (T->lchild ) 
        newlptr = CopyTree(T->lchild); //復制左子樹
    else 
        newlptr = NULL;
    
    if (T->rchild ) 
        newrptr = CopyTree(T->rchild); //復制右子樹
    else    
        newrptr = NULL;
    
    newT = GetTreeNode(T->data, newlptr, newrptr);
    return newT;
} // CopyTree

  1. 按給定的表達式建相應二叉樹
typedef struct node
{
    ElemType data;    
    float val;
	char optr;    //只取‘+’,  ‘-’,  ‘*’,‘/’
	struct node *lchild,*rchild;
}BiNode,*BiTree;

float PostEval(BiTree bt) 
{    
    float lv,rv;
    if(bt! = null)
    {
        lv = PostEval(bt->lchild); // 求左子樹表示的子表達式的值
    	rv = PostEval(bt->rchild); // 求右子樹表示的子表達式的值
    	switch(bt->optr)
    	{ 
            case '+': value = lv+rv; 	break;
            case '-': value = lv-rv;	break;
            case '*': value = lv*rv;	break;
            case '/': value = lv/rv;
    	}
    } 
    return(value); 
}

  1. 按層次遍歷二叉樹
void LevelOrder(BiTree b)
{
    BiTree Queue[MAX_TREE_SIZE];
    int front,rear;
    if (b == NULL) 
        return;
    front = -1; 
    rear = 0;
    Queue[rear] = b;
    while(front != rear) 
    {
      Visit(Queue[++front]->data); //訪問隊首結點數據域
      if (Queue[front]->lchild != NULL)       
            Queue[++rear] = Queue[front]->lchild;
      if (Queue[front]->rchild != NULL)     
          Queue[++rear] = Queue[front]->rchild;
    }
}

  1. 求森林的深度
typedef struct CSNode{
    int  data;
    struct CSNode *firstchild, *nextsibling;
}CSNode, *CSTree;

int Depth(CSTree T)
{
    if (T==NULL)    
        return 0;
    else
    {
        d1 = Depth(T->firstchild);
        d2 = Depth(T->nextsibling);
        return Max(d1+1,d2);
    }
}

  1. 假設二叉樹采用二叉鏈表存儲結構存儲,設計一個算法,利用結點的右孩子指針 rchild 將一棵二叉樹的葉子結點按從左往右的順序串成一個單鏈表。
void link(BiTree bt, BiTNode *head, BiTNode *tail)
{ 
    //初始調用時 head = NULL
    if (bt! = NULL)
    {
    	if (bt->lchild == NULL && bt->rchild == NULL)   
        	if (head == NULL)
            {   
                //第一個葉子結點
      			head = bt;
      			tail = head;
             }
        else
        {
            tail->rchild = bt;
            tail = bt;
        }
        if (bt->lchild! = NULL) 
            link(bt->lchild,head,tail);
        if (bt->rchild! = NULL) 
            link(bt->rchild,head,tail);
    }
}

  1. 編寫遞歸算法,求二叉樹中以元素值為 x 的結點為根的子樹的深度。
int Get_Sub_Depth(Bitree T,int x) {
    if(T->data == x)
    {
        printf("%d\n",Get_Depth(T)); //找到值為 x 的結點,求其深度
        exit 1;
    }
    else
    {
        if(T->lchild) 	//在左子樹中繼續尋找
            Get_Sub_Depth(T->lchild,x);
        if(T->rchild)   //在右子樹中繼續尋找
            Get_Sub_Depth(T->rchild,x); 
    }
}

int Get_Depth(Bitree T) 
{
    //求子樹深度的遞歸算法
    if(!T)    
        return 0;
    else
    {
        m = Get_Depth(T->lchild);
        n = Get_Depth(T->rchild);
        return (m>n ?m :n)+1;
    }
}

  1. 設樹 T 采用孩子兄弟鏈表存儲結構,設計算法求樹 T 的葉子數目。
void LeafCount_CSTree(CSTree T)
{
    if(!T->FirstChild) 
        return 1;		//葉子結點
    else
    {
        count=0;
        for(p=T->FirstChild;p;p->NextSibling)
        	count += LeafCount_CSTree(p);
        return count; 	//各子樹的葉子數之和
    }
}

  1. 編寫算法求以孩子—兄弟表示法存儲的森林的葉子結點數。
typedef struct node
{
    ElemType data; //數據域
	struct  node *fch, *nsib; //孩子與兄弟域
}*Tree;

int Leaves (Tree t) 
{    
    if(t = null) 
        return 0;
	else if(t->fch == null) //若結點無孩子,則該結點必是葉子
        return( 1 + Leaves(t->nsib));       
  	else 
      return ( Leaves(t->fch) + Leaves(t->nsib) );   
}

  1. 試編寫求無向圖 G 的連通分量的算法。要求輸出每一連通分量的頂點值。
void DFS()
{
    visited[v]=1; 
    printf("%3d",v); 	//輸出連通分量的頂點
    p=g[v].firstarc;    
    while (p!=NULL)
    {
        if(visited[p->adjvex==0])
          DFS(p->adjvex);
        p=p->next;
    }
}

void  Count( )
{
    //求圖中連通分量的個數
	int k=0 ; 
    static AdjList g ; 
	//設無向圖 g 有 n 個結點
	for (i=1;i<=n;i++ )
		if (visited[i]= =0) 
        { 
  			printf ("\n 第%d 個連通分量:\n",++k); 
			DFS(i);
		}
}

  1. 設二叉排序樹已經以二叉鏈表的形式存儲在內存中,使用遞歸方法,求各結點的平衡因子並輸出。
typedef struct BiTNode
{
    int bf;  //平衡因子
    int data;
    struct BiTNode *lchild;*rchild; //左、右孩子指針
}BiTNode,*BiTree;

int Computerbf(BiTree bt)
{
    int hl,hr;
    if (bt =  = NULL) 
        return 0;            //空樹無平衡因子
    if (bt->lchild =  = NULL&& bt->rchild =  = NULL)
    {
        bt->bf = 0;          //無左、右孩子的結點,平衡因子為 0
        printf(bt->data);printf(bt->bf);      
        return 1;
    }
    else 
    {	
        //有左、右子樹的結點,其平衡因子為左、右子樹高度之差
        hl = Computerbf(bt->lchild); 
        hr = Computerbf(bt->rchild);
        bt->bf = hl-hr;
        printf(bt->data);
        printf(bt->bf);
        return (1+(hl>hr ? hl:hr));    
    }   
}

  1. 請編寫一個雙向起泡的排序算法,即每一趟通過每兩個相鄰的關鍵字進行比較,產生最小和最大的元素。
void Bubble_Sort2(int a[],int n) 
{
    //相鄰兩趟向相反方向起泡的冒泡排序算法
    low = 0; 
    high = n-1;                //冒泡的上下界
    change = 1;
    while(low < high && change) 
    {
        change = 0;                        //設不發生交換
        for(i = low;i < high;i++)        //從上向下起泡
              if(a[i] > a[i+1])
              {
                  a[i]<->a[i+1];
         		  change = 1;
              }
        high--;           //修改上界
        for(i = high; i>low; i--)          //從下向上起泡
        	if(a[i] <a[i-1])
        	{
                a[i]<->a[i-1];
        		change = 1;
            }
        low++;                      //修改下界
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM