1. 程式人生 > >判斷一個連結串列是不是迴文數

判斷一個連結串列是不是迴文數

要求O(n)時間

1. 使用2個指標,快慢指標各一個,每次快指標移動一個,慢指標移動2個。

2. 當快指標不為NULL時候,將慢指標push到棧中。

3. 當快指標等於NULL時候,說明連結串列前半部分已經被壓入棧中。

4. 每次棧Top元素與當前慢指標元素比較,如果不相等則返回false。如果相等,則棧Pop,慢指標++。

5. 連結串列奇數或者偶數節點需要判斷(如果為奇數那麼就刪除最後的棧頂)。

#include<cstdio>
#include<cstdlib>
#include<stack>
using namespace std;

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

//頭插法建立單鏈表
LinkedList * creatLinkedList(){
    LinkedList *head , *q;
    int num;
    head = (Node *)malloc(sizeof(Node));
    head->next = NULL;
    printf("請輸入你要插入的資料:(輸入0結束)\n");
    scanf("%d",&num);
    while(num != 0){
        q = (Node *)malloc(sizeof(Node));
        q->data = num;
        q->next = head->next;
        head->next = q;
        scanf("%d",&num);
    }
    return head;
}

//列印單鏈表
void printLinkedList(LinkedList * head)
{
    LinkedList *p;
    p = head->next;
    while(p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
}

//判斷單鏈表是不是迴文連結串列
bool isPalindrome(LinkedList *head)
{
    stack<int> sk;
    LinkedList *fast = head->next;
    LinkedList *slow = head->next;
    int flag = 0;
    while(fast !=NULL)
    {
        sk.push(slow->data);
        slow = slow->next;
        fast = fast->next;
        if(fast != NULL){
            fast = fast->next;
        }else{
            flag = 1;
        }
    }
    if(flag == 1){
        sk.pop();
    }

    while(!sk.empty())
    {
        if(sk.top() == slow->data)
        {
            sk.pop();
            slow = slow->next;
        }
        else
            return false;
    }
    return true;
}

int main()
{
    LinkedList *head;
    head = creatLinkedList();
    printf("連結串列內容如下:");
    printLinkedList(head);
    printf("\n\n");
    if(isPalindrome(head))
    {
        printf("該連結串列是一個迴文連結串列!\n");
    }
    else
    {
        printf("該連結串列不是一個迴文連結串列!\n");
    }
    return 0;
}