數據結構——鏈表(4)如何尋找到單鏈表中間的結點【特殊的找第k個結點的方法】

方法一:首先遍歷一次,求得單鏈表長度len,然後再遍歷一次,找到(len+1)/2的中間位置。

方法二:和找第k個結點類似,但是因爲是中間結點,又有一定的特殊性。定義兩個結點指針p和q,最開始都表示頭指針,然後,p每次移動一位,q每次移動兩位;當q移到最後一個結點時,p結點就在中間位置。
具體代碼實現如下:

#include <stdlib.h>
#include<iostream>


typedef int ElemType;
struct Node
{
    ElemType data;
    struct Node *next;
};

typedef struct Node Node;
typedef struct Node* Linklist;


#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MaxSize 30  //存儲空間初始分配量
typedef int Status;


Status InitList1(Linklist *L)
{
    *L= (Linklist)malloc(sizeof(Node)); //產生頭結點,並且使得L指向該頭結點
    if (!(*L))  
        return ERROR;                           //令頭結點的指針域爲空
    (*L)->next = NULL;
    return OK;

}

//獲取鏈表的長度
int ListLength1(Linklist L)
{
    Linklist p;
    p=L->next;
    int len=0;
    while(p)
    { 
        p=p->next;
        len++;
    }
    return len;
}



//對鏈表進行頭插法
Status ListInsert1(Linklist *L,int i, ElemType e)
{
    Linklist p,s;
    p=(*L);
    int j=1;
    while(p && j<i)
    {
        p=p->next;
        j++;
    }
    if (!p || j>i)
        return ERROR;

    s=(Linklist)malloc(sizeof(Node));
    s->data=e;
    s->next =p->next;
    p->next =s;
    return OK;



}



/*  從頭到尾輸出鏈表元素  */
Status ListTraverse1(Linklist L)
{
    Linklist p;
    p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    return OK;
}


/*找到鏈表中間元素並輸出*/
using namespace std;
void findListMiddle(Linklist L,int &num)
{
    int count=0;
    Linklist p=L;
    int len=ListLength1(L);
    int mid=(len+1)/2;
    for (int i=1;i<=mid;i++)
    {
        p=p->next;
        count++;
    }
    num=p->data;
    cout<<num<<endl;
    //cout<<count<<endl;

}

void findListMiddle2(Linklist L, int &num)
{
    Linklist p=L;
    Linklist q=L;

        while(L != NULL && q!=NULL && q->next!=NULL)    //注意這裏要用與運算!!而不是或。
        {
            p=p->next;
            int i =p->data;
            q=q->next->next;
        //  int j=q->data;
        }

    num=p->data;
    cout<<num<<endl;
}

int main()
{
    Linklist L;
    InitList1(&L);          //首先,要初始化一個鏈表

    int len1=ListLength1(L);
    printf("初始化鏈表長度爲:%d\n",len1);

    //在表頭位置依次插入12345,最後,鏈表中存放的是5->4->3->2->1
    for (int i=1;i<=6;i++)
    {
        ListInsert1(&L,1,i);
    }
    printf("\n第一次插入數據,長度爲:");
    int len2=ListLength1(L);
    printf("%d\n",len2);

    printf("\n對正序的鏈表輸出:");
    Linklist p =L;
    for(int i=1;i<=len2;i++)
    {
        printf("%d ",p->next->data);
        p=p->next;
    }


    printf("找到單鏈表中間結點:方法一\n");
    int num1=0;
    findListMiddle(L,num1);

    printf("找到單鏈表中間結點:方法二\n");
    int num2;
    findListMiddle2(L,num2);

    getchar();

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章