連結串列反轉(使用遞迴和非遞迴兩種方式)
阿新 • • 發佈:2019-01-24
#include <stdio.h>
#include <iostream>
using namespace std;
//連結串列的資料結構
typedef struct lNode
{
int data;
struct lNode *next;
}linkList;
//判斷連結串列是否為空的方法
bool isEmpty(linkList *&L){
return (L->next == NULL);
}
//初始化連結串列
linkList* initLinklist(linkList *&head,int data){
head = (linkList *)malloc(sizeof(head));
head->data = data;
head->next = NULL;
cout<<"初始化連結串列成功"<<endl;
return head;
}
//給連結串列尾部新增結點
void tailNodePlus(linkList *&head,int data){
linkList* newNode = new linkList;
if(isEmpty(head)){
head->next = newNode;
newNode-> data = data;
//cout<<newNode->next<<endl;
newNode -> next = NULL;
cout<<"連結串列結點插入成功"<<endl;
}else{
linkList* tempNode = head;
//找到尾結點
while(tempNode->next != NULL){
tempNode = tempNode->next;
}
tempNode-> next = newNode;
newNode->data = data;
newNode->next = NULL;
//連結串列結點插入成功
cout<<"連結串列結點插入成功"<<endl;
}
}
//將連結串列中的內容輸出
void printLinkList(linkList *L){
if(L == NULL){
return;
}
while(L->next != NULL){
cout<<L->data<<'\t';
L = L->next;
}
cout<<L->data;//輸出最後一個連結串列結點的值
}
//將生成的連結串列反轉(遞迴的方法,不考慮使用額外的儲存空間)
linkList* reverseLinkList(linkList *head){
if(head == NULL || head->next == NULL){
return head;
}else{
linkList* newHead = reverseLinkList(head->next);//先反轉連結串列後面的元素
head->next->next = head;
head->next = NULL;
return newHead;
}
}
//將生成的連結串列反轉(用非遞迴的方法,需要額外的的結點儲存空間)
linkList* reverseLinkList2(linkList *head){
linkList *currentNode = head;//快取第一個結點
linkList *nextNode = head->next;//快取第二個結點
head->next = NULL;//將尾結點作為特殊情況在迴圈外面做特殊對待
while(nextNode != NULL){
currentNode = nextNode;//此時的currentNode應該向前推進一個
nextNode = nextNode->next;//nextNode也應該向前推進一個
currentNode->next = head;//修改指標的指向
head = currentNode;//讓head結點始終為連結串列反序後的頭結點
}
return head;
}
/*測試一下*&
void test(linkList *&head){
cout<<head<<endl;
linkList* node = head;
cout<<node<<endl;
}*/
int main(int argc, char *argv[])
{
linkList *head = new linkList;
head = initLinklist(head,1);
tailNodePlus(head,2);
tailNodePlus(head,3);
tailNodePlus(head,4);
/*linkList* reverseHead = reverseLinkList2(head);//非遞迴的方法獲取新的頭結點
printLinkList(reverseHead);//反轉的目的已經達到,輸出4 3 2 1*/
linkList* reverseHead2 = reverseLinkList(head);//遞迴的方式獲取新的頭結點
printLinkList(reverseHead2);//反轉的目的已經達到,輸出4 3 2 1
return 0;
}