Danh sách liên kết ngược python đệ quy
Chúng tôi đã thảo luận về một giải pháp lặp lại để đảo ngược danh sách được liên kết trong bài viết trước. Trong bài đăng này, chúng tôi sẽ đề cập đến việc thực hiện đệ quy của nó Show Sau đây là cách triển khai đệ quy đơn giản hoạt động bằng cách sửa con trỏ C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include #include
// Một nút danh sách liên kết struct Nút { int dữ liệu; struct Nút* tiếp theo; };
// Hàm trợ giúp để in danh sách liên kết đã cho void printList(struct Nút* head) { struct Nút* ptr = head; trong khi (ptr) { printf("%d —> ", ptr->data); ptr = ptr->next; }
printf("NULL\n")<; }
// Hàm trợ giúp chèn một nút mới vào đầu danh sách liên kết void đẩy(struct Nút** head, int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->dữ liệu = data; newNode->next = *head;
*head = newNode; }
// Hàm đệ quy để đảo ngược danh sách liên kết đã cho. Nó đảo ngược // danh sách liên kết đã cho bằng cách cố định con trỏ đầu và sau đó `. tiếp theo` // con trỏ của mọi nút theo thứ tự ngược lại void recursiveReverse(struct Nút* head, struct Node** headRef) { struct Nút* đầu tiên; struct Nút* phần còn lại;
// trường hợp cơ sở danh sách trống nếu (đầu == NULL) { trả lại; }
đầu = đầu; // suppose first = {1, 2, 3} nghỉ ngơi = đầu tiên->next; // rest = {2, 3}
// trường hợp cơ bản. danh sách chỉ có một nút nếu (nghỉ ngơi == NULL) { // sửa con trỏ đầu ở đây *headRef = đầu tiên; trả lại; }
// đảo ngược đệ quy trường hợp {2, 3} nhỏ hơn // sau. phần còn lại = {3, 2} recursiveReverse(rest, headRef);
// đặt mục đầu tiên vào cuối danh sách nghỉ ngơi->tiếp theo = first; đầu tiên->tiếp theo = NULL; // (tricky step — make a drawing) }
// Đảo ngược danh sách liên kết đã cho. Hàm lấy một con trỏ // (tham chiếu) đến con trỏ đầu void reverse(struct Nút** head) { recursiveReverse(*head, head); }
int chính(void) { // phím nhập int phím[] = { 1, 2, 3, 4, 5, 6 }; int n = sizeof(keys)/sizeof(keys[0]);
struct Nút* đầu = NULL; cho (int i = n - 1; i >=0; i--) { đẩy(&đầu, keys[i]); }
lùi(&ngửa); printList(đầu);
return 0; } Tải xuống Chạy mã Đầu ra. C++1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include #include sử dụng không gian tên std;
// Một nút danh sách liên kết struct Nút { int dữ liệu; Nút* tiếp theo; };
// Hàm trợ giúp để in danh sách liên kết đã cho void printList(Nút* head) { Nút* ptr = head; trong khi (ptr) { cout << ptr->data << " —> "; ptr = ptr->next; }
cout << "nullptr" <<< endl; }
// Hàm trợ giúp chèn một nút mới vào đầu danh sách liên kết void đẩy(Nút* &headRef, int data) { Nút* Node mới = new Node(); newNode->dữ liệu = data; newNode->next = headRef;
headRef = newNode; }
// Hàm đệ quy để đảo ngược danh sách liên kết đã cho. Nó đảo ngược // danh sách liên kết đã cho bằng cách cố định con trỏ đầu và sau đó `. tiếp theo` // con trỏ của mọi nút theo thứ tự ngược lại void recursiveReverse(Nút* head, Node* &headRef) { Nút* đầu tiên; Nút* nghỉ ngơi;
// trường hợp cơ sở danh sách trống nếu (đầu == nullptr) { trả lại; }
đầu = đầu; // suppose first = {1, 2, 3} nghỉ ngơi = đầu tiên->next; // rest = {2, 3}
// trường hợp cơ bản. danh sách chỉ có một nút nếu (nghỉ ngơi == nullptr) { // sửa con trỏ đầu ở đây headRef = đầu tiên; trả lại; }
// đảo ngược đệ quy trường hợp {2, 3} nhỏ hơn // sau. phần còn lại = {3, 2} recursiveReverse(rest, headRef);
// đặt mục đầu tiên vào cuối danh sách nghỉ ngơi->tiếp theo = first; đầu tiên->tiếp theo = nullptr; // (tricky step — make a drawing) }
// Đảo ngược danh sách liên kết đã cho. Hàm lấy một con trỏ // (tham chiếu) đến con trỏ đầu void reverse(Nút* &headRef) { recursiveReverse(headRef, headRef); }
int chính() { // phím nhập vectơ<int> keys = { 1, 2, 3, 4, 5, 6 };
Nút* đầu = nullptr; cho (int i = keys.kích thước() - 1; i >=0; i--) { đẩy(đầu, keys[i]); }
lùi(đầu); printList(đầu);
return 0; } Tải xuống Chạy mã Đầu ra. Java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 // Một nút danh sách liên kết lớp Nút { int dữ liệu; Nút tiếp theo;
Nút(int dữ liệu) { cái này. dữ liệu = dữ liệu; } }
lớp Chính { // Hàm trợ giúp để in danh sách liên kết đã cho công khai tĩnh vô hiệu printList(Node head) { Nút ptr = đầu; trong khi (ptr . = null) { Hệ thống. ra. in(ptr. dữ liệu + " —> "); ptr = ptr. tiếp theo; } Hệ thống. ra. println("null"); }
// Hàm trợ giúp để chèn một nút mới vào đầu danh sách được liên kết công khai tĩnh Nút đẩy(Node head, int data) { Nút nút = mới Node(data); nút. tiếp theo = đầu; return node; }
// Hàm đệ quy để đảo ngược danh sách liên kết đã cho. Nó đảo ngược // danh sách được liên kết đã cho bằng cách cố định con trỏ đầu và sau đó `. tiếp` // con trỏ của mọi nút theo thứ tự đảo ngược công khai tĩnh Nút nghịch(Node head, Node headRef) { Nút đầu tiên, nghỉ ngơi;
// trường hợp cơ sở danh sách trống nếu (đầu == null) { return headRef; }
đầu = đầu; // suppose first = {1, 2, 3} nghỉ ngơi = trước. tiếp theo; // phần còn lại = {2, 3}
// trường hợp cơ bản. danh sách chỉ có một nút nếu (nghỉ ngơi == null) { // sửa con trỏ đầu ở đây headRef = đầu tiên; return headRef; }
// đảo ngược đệ quy trường hợp {2, 3} nhỏ hơn // sau. phần còn lại = {3, 2} headRef = reverse(rest, headRef);
// đặt mục đầu tiên vào cuối danh sách nghỉ ngơi. tiếp theo = đầu tiên; đầu tiên. tiếp theo = null; <// (tricky step — make a drawing)
return headRef; }
// Đảo ngược danh sách liên kết đã cho. Hàm lấy một tham chiếu đến // nút đầu công khai tĩnh Nút nghịch(Node head) { lùi lùi(đầu, head); }
công khai tĩnh vô hiệu chính(String[] args) { // phím nhập int[] phím = { 1, 2, 3, 4, 5, 6 };
Nút đầu = null; cho (int i = keys.độ dài - 1; i >=0; i--) { đầu = đẩy(head, keys[i]); }
đầu = lùi(head); inDanh sách(đầu); } } Tải xuống Chạy mã Đầu ra. con trăn1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 # Nút danh sách được liên kết lớp Nút. def __init__(self, data, next=None): bản thân. dữ liệu = dữ liệu bản thân. tiếp theo = tiếp theo
# Hàm in danh sách liên kết cho trước def printList(đầu):
ptr = đầu while ptr. in(ptr. dữ liệu, kết thúc=') ptr = ptr. tiếp theo in('Không')
# Hàm đệ quy để đảo ngược danh sách liên kết đã cho. Nó đảo ngược # đã cho danh sách liên kết bằng cách cố định con trỏ đầu và sau đó `. tiếp theo` # con trỏ của mọi nút theo thứ tự ngược lại def ngược(đầu, headRef):
# trường hợp cơ sở danh sách trống nếu đầu là Không có: return headRef
đầu = đầu # suppose first = [1, 2, 3] nghỉ ngơi = trước. tiếp theo # rest = [2, 3]
# trường hợp cơ bản. danh sách chỉ có một nút nếu nghỉ ngơi là Không: # sửa con trỏ theo đầu tại đây headRef = đầu tiên return headRef
# đảo ngược đệ quy trường hợp {2, 3} nhỏ hơn # sau. còn lại = [3, 2] headRef = reverse(rest, headRef)
# đặt mục đầu tiên vào cuối danh sách nghỉ ngơi. tiếp theo = đầu tiên đầu tiên. tiếp theo = Không có # (
return headRef
# Đảo ngược danh sách liên kết đã cho def reverseList(head): quay lại ngược lại(đầu, head)
if __name__ == '__main__'.
đầu = Không cho i trong đảo ngược(range(6)): đầu = Nút(i + 1, head)
đầu = reverseList(head) printList(đầu)
Tải xuống Chạy mã Đầu ra. Chúng ta cũng có thể giải quyết vấn đề này bằng cách chỉ chuyển tham chiếu đến con trỏ head đến hàm, như minh họa bên dưới C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #include #include
// Một nút danh sách liên kết struct Nút { int dữ liệu; struct Nút* tiếp theo; };
// Hàm trợ giúp để in danh sách liên kết đã cho void printList(struct Nút* head) { struct Nút* ptr = head; trong khi (ptr) { printf("%d —> ", ptr->data); ptr = ptr->next; }
printf("NULL\n")<; }
// Hàm trợ giúp chèn một nút mới vào đầu danh sách liên kết void đẩy(struct Nút** head, int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->dữ liệu = data; newNode->next = *head;
*head = newNode; }
// Hàm đệ quy đảo ngược danh sách liên kết. Nó đảo ngược đã cho // danh sách được liên kết bằng cách cố định con trỏ đầu và sau đó `. con trỏ next` // của mọi nút theo thứ tự ngược lại void reverse(struct Nút** head) { struct Nút* đầu tiên; struct Nút* phần còn lại;
// trường hợp cơ sở danh sách trống nếu (*đầu == NULL) { trả lại; }
đầu = *đầu; // suppose first = {1, 2, 3} nghỉ ngơi = đầu tiên->next; // rest = {2, 3}
// trường hợp cơ sở còn lại trống nếu (nghỉ ngơi == NULL) { trả lại; }
đảo ngược(&nghỉ ngơi); // recursively reverse the smaller {2, 3} case // sau. phần còn lại = {3, 2}
đầu tiên->tiếp theo->next = first; // put the first item at the end of the list đầu tiên->tiếp theo = NULL; // (tricky step — make a drawing) *đầu = nghỉ ngơi; // fix the head pointer }
int chính(void) { // phím nhập int phím[] = { 1, 2, 3, 4, 5, 6 }; int n = sizeof(keys)/sizeof(keys[0]);
struct Nút* đầu = NULL; cho (int i = n - 1; i >=0; i--) { đẩy(&đầu, keys[i]); }
lùi(&ngửa); printList(đầu);
return 0; } Tải xuống Chạy mã Đầu ra. C++1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include #include sử dụng không gian tên std;
// Một nút danh sách liên kết struct Nút { int dữ liệu; Nút* tiếp theo; };
// Hàm trợ giúp để in danh sách liên kết đã cho void printList(Nút* head) { Nút* ptr = head; trong khi (ptr) { cout << ptr->data << " —> "; ptr = ptr->next; }
cout << "nullptr" <<< endl; }
// Hàm trợ giúp chèn một nút mới vào đầu danh sách liên kết void đẩy(Nút* &headRef, int data) { Nút* Node mới = new Node(); newNode->dữ liệu = data; newNode->next = headRef;
headRef = newNode; }
// Hàm đệ quy đảo ngược danh sách liên kết. Nó đảo ngược đã cho // danh sách được liên kết bằng cách cố định con trỏ đầu và sau đó `. con trỏ next` // của mọi nút theo thứ tự ngược lại // Hàm lấy tham chiếu đến con trỏ head void reverse(Nút* &headRef) { Nút* đầu tiên; Nút* nghỉ ngơi;
// trường hợp cơ sở danh sách trống if (headRef == nullptr) { trả lại; }
first = headRef; // suppose first = {1, 2, 3} nghỉ ngơi = đầu tiên->next; // rest = {2, 3}
// trường hợp cơ sở còn lại trống nếu (nghỉ ngơi == nullptr) { trả lại; }
đảo ngược(nghỉ ngơi); // recursively reverse the smaller {2, 3} case // sau. phần còn lại = {3, 2}
đầu tiên->tiếp theo->next = first; // put the first item at the end of the list đầu tiên->tiếp theo = nullptr; // (tricky step — make a drawing) headRef = nghỉ ngơi; // fix the head pointer }
int chính() { // phím nhập vectơ<int> keys = { 1, 2, 3, 4, 5, 6 };
Nút* đầu = nullptr; cho (int i = keys.kích thước() - 1; i >=0; i--) { đẩy(đầu, keys[i]); }
lùi(đầu); printList(đầu);
return 0; } Tải xuống Chạy mã Đầu ra. Java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 // Một nút danh sách liên kết lớp Nút { int dữ liệu; Nút tiếp theo;
Nút(int dữ liệu) { cái này. dữ liệu = dữ liệu; } }
lớp Chính { // Hàm trợ giúp để chèn một nút mới vào đầu danh sách được liên kết công khai tĩnh Nút đẩy(Node head, int data) { Nút nút = mới Node(data); nút. tiếp theo = đầu; return node; }
// Hàm trợ giúp để in danh sách liên kết đã cho công khai tĩnh vô hiệu printList(Node head) { Nút ptr = đầu; trong khi (ptr . = null) { Hệ thống. ra. in(ptr. dữ liệu + " —> "); ptr = ptr. tiếp theo; } Hệ thống. ra. println("null"); }
// Hàm đệ quy đảo ngược danh sách liên kết. // Nó đảo ngược danh sách liên kết đã cho bằng cách cố định con trỏ đầu và // sau đó `. next` con trỏ của mọi nút theo thứ tự ngược lại công khai tĩnh Nút nghịch(Node head) { Nút đầu tiên, nghỉ ngơi;
// trường hợp cơ sở danh sách trống nếu (đầu == null) { trả về đầu; }
đầu = đầu; // suppose first = {1, 2, 3} nghỉ ngơi = trước. tiếp theo; // phần còn lại = {2, 3}
// trường hợp cơ sở còn lại trống nếu (nghỉ ngơi == null) { trả về đầu; }
nghỉ ngơi = đảo ngược(rest); // recursively reverse the smaller {2, 3} case // sau. phần còn lại = {3, 2}
đầu tiên. tiếp theo. tiếp theo = đầu tiên; <// put the first item at the end of the list đầu tiên. tiếp theo = null; <// (tricky step — make a drawing) đầu = nghỉ ngơi; // fix the head pointer
trả về đầu; }
công khai tĩnh vô hiệu chính(String[] args) { // phím nhập int[] phím = { 1, 2, 3, 4, 5, 6 };
Nút đầu = null; cho (int i = keys.độ dài - 1; i >=0; i--) { đầu = đẩy(head, keys[i]); }
đầu = lùi(head); inDanh sách(đầu); } } Tải xuống Chạy mã Đầu ra. con trăn1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 # Nút danh sách được liên kết lớp Nút. def __init__(self, data, next=None): bản thân. dữ liệu = dữ liệu bản thân. tiếp theo = tiếp theo
# Hàm in danh sách liên kết cho trước def printList(đầu):
ptr = đầu while ptr. in(ptr. dữ liệu, kết thúc=') ptr = ptr. tiếp theo
in('Không')
# Hàm đệ quy đảo ngược danh sách liên kết # Nó đảo ngược danh sách liên kết đã cho bằng cách cố định con trỏ đầu và # sau đó `. con trỏ next` của mọi nút theo thứ tự ngược lại def nghịch(đầu):
# trường hợp cơ sở danh sách trống nếu đầu là Không có: về đầu
đầu = đầu # suppose first = [1, 2, 3] nghỉ ngơi = trước. tiếp theo # rest = [2, 3]
# trường hợp cơ sở còn lại trống nếu nghỉ ngơi là Không: về đầu
nghỉ ngơi = đảo ngược(rest) # recursively reverse the smaller {2, 3} case # sau. còn lại = [3, 2]
đầu tiên. tiếp theo. tiếp theo = đầu tiên # đặt đầu tiên. tiếp theo = Không có # ( đầu = nghỉ ngơi # fix the head pointer
trả về đầu
if __name__ == '__main__'.
đầu = Không cho i trong đảo ngược(range(6)): đầu = Nút(i + 1, head)
đầu = lùi(head) printList(đầu)
Tải xuống Chạy mã Đầu ra. Chúng ta có thể đơn giản hóa đoạn mã trên bằng cách chuyển thông tin nút trước đó cho hàm. Sau đây là cách triển khai đệ quy đơn giản của nó trong C, C++, Java và Python Bạn có thể đảo ngược danh sách liên kết bằng đệ quy không?Cách tiếp cận đệ quy để đảo ngược danh sách liên kết rất đơn giản, chúng ta chỉ cần chia danh sách liên kết thành hai phần và tôi. e nút đầu tiên và phần còn lại của danh sách được liên kết, sau đó gọi đệ quy cho phần khác bằng cách duy trì kết nối
Bạn có thể đảo ngược danh sách được liên kết trong Python không?Danh sách được liên kết có thể được đảo ngược theo cách lặp lại hoặc đệ quy .
Cách tốt nhất để đảo ngược một danh sách được liên kết là gì?Để đảo ngược một Danh sách được liên kết theo cách đệ quy, chúng ta cần chia Danh sách được liên kết thành hai phần. đầu và còn lại . Head trỏ đến phần tử đầu tiên ban đầu. Các điểm còn lại đến phần tử tiếp theo từ phần đầu. Chúng tôi duyệt đệ quy LinkedList cho đến phần tử cuối cùng thứ hai.
Làm thế nào đệ quy có thể được thực hiện trên danh sách được liên kết?Lệnh gọi đệ quy được áp dụng cho danh sách liên kết nhỏ hơn nghiêm ngặt (chứa ít nút hơn). Giả định độ dài(l. next) tính toán chính xác độ dài của danh sách sau nút đầu tiên, sau đó trả về giá trị lớn hơn một giá trị sẽ tính toán chính xác độ dài của toàn bộ danh sách . |