Circular Linked List是一種連結串列的資料結構,它與一般的單向鏈結串列不同的地方在於它結尾的節點會指向頭部節點,形成一個循環的連結串列。因此,當我們訪問最後一個節點時,它指向的是頭部節點而不是NULL。
以下是一個示範Circular Linked List的圖表:
1 -> 2 -> 3 -> 4 -> 1
在上面的例子中,我們可以看到最後一個節點指向第一個節點,因此它是一個圓形的連結串列。當我們查詢最後一個節點時,程式碼就會跳回第一個節點,進入一個循環,因為每個節點都指向下一個節點,直到最後一個節點再指向第一個節點。這使得操作和查詢Circular Linked List的時間複雜度相較於Linked List更高效。
在實現Circular Linked List時,我們需要在每個節點中維護指向下一個節點的指標,並且保證最後一個節點指向第一個節點。
以下是一個示範建立Circular Linked List的程式碼:
typedef struct Node {
int value;
struct Node *next;
} Node;
Node *createCircularLinkedList(int values[], int n) {
Node *head = NULL;
Node *prev = NULL;
Node *curr = NULL;
for (int i = 0; i < n; i++) {
curr = malloc(sizeof(Node));
curr->value = values[i];
curr->next = NULL;
if (prev) {
prev->next = curr;
} else {
head = curr;
}
prev = curr;
}
if (curr) {
curr->next = head;
}
return head;
}
void reverse(Node** head)
{
if (*head == NULL)
return;
Node* prev = NULL;
Node* current = *head;
Node* next;
do
{
next = current->next;
current->next = prev;
prev = current;
current = next;
} while (current != *head);
(*head)->next = prev;
*head = prev;
}
void removeNode(Node** head, int key)
{
if (*head == NULL)
return;
Node* current = *head;
Node* prev;
do
{
if (current->data == key)
{
if (current == *head)
*head = current->next;
prev->next = current->next;
free(current);
current = prev->next;
}
else
{
prev = current;
current = current->next;
}
} while (current != *head);
}
bool isPalindrome(Node* head)
{
if (head == NULL)
return true;
Node *slow_ptr = head, *fast_ptr = head;
Node *prev_of_slow_ptr = head;
Node* midnode = NULL;
bool res = true;
if (head != NULL && head->next != NULL)
{
while (fast_ptr != NULL && fast_ptr->next != NULL)
{
fast_ptr = fast_ptr->next->next;
prev_of_slow_ptr = slow_ptr;
slow_ptr = slow_ptr->next;
}
if (fast_ptr != NULL)
{
midnode = slow_ptr;
slow_ptr = slow_ptr->next;
}
Node* second_half = slow_ptr;
prev_of_slow_ptr->next = NULL;
reverse(&second_half);
res = compareLists(head, second_half);
reverse(&second_half);
if (midnode != NULL)
{
prev_of_slow_ptr->next = midnode;
midnode->next = second_half;
}
else
prev_of_slow_ptr->next = second_half;
}
return res;
}
bool compareLists(Node* head1, Node* head2)
{
Node* temp1 = head1;
Node* temp2 = head2;
while (temp1 && temp2)
{
if (temp1->data == temp2->data)
{
temp1 = temp1->next;
temp2 = temp2->next;
}
else
return false;
}
if (temp1 == NULL && temp2 == NULL)
return true;
return false;
}
Node* sortedMerge(Node* a, Node* b)
{
if (a == NULL)
return b;
if (b == NULL)
return a;
Node* result = NULL;
if (a->data <= b->data)
{
result = a;
result->next = sortedMerge(a->next, b);
}
else
{
result = b;
result->next = sortedMerge(a, b->next);
}
return result;
}
Node* mergeSort(Node* head)
{
if (head == NULL || head->next == head)
return head;
Node *slow = head, *fast = head->next;
while (fast != head && fast->next != head)
{
slow = slow->next;
fast = fast->next->next;
}
Node* second_half = slow->next;
slow->next = head;
head = mergeSort(head);
second_half = mergeSort(second_half);
return sortedMerge(head, second_half);
}
int getMax(Node* head)
{
if (head == NULL)
return -1;
int max = head->data;
Node* temp = head->next;
while (temp != head)
{
if (temp->data > max)
max = temp->data;
temp = temp->next;
}
return max;
}