#include <iostream>
using namespace std;
class List {
public:
//节点结构
struct Node{
int data;
Node * next;
Node(const int& d):data(d),next(NULL){}
};
Node *head;//头节点
public:
List(){create_List();}
~List(){}
//创建头结点
void create_List();
Node *insert(const int& d);
Node *reverse(Node *head);
Node *recursive_reverse(Node *head);
void print(Node *hd);
void print(Node *hd,int i);
};
void List::create_List(){
head = new Node(0);
}
//尾插法建立链表
List::Node* List::insert(const int& d)
{
Node *current;
current = head; //current和head的data和next域相同,current = head; current->next = head->next = NULL; head->next存的是下一个节点的首地址.
for(int i = 0; i< d; i++){
Node *p = new Node(i);
current->next = p;//将新建的p节点插入;如新申请p地址0x10,current->next
current = p; //将r指向p,从而可以继续向后面插入
}
current->next = NULL;//将尾结点赋值为空
return head;
}
//打印函数
void List::print(Node *hd){
for(Node *p = hd->next; p != NULL; p=p->next)
cout << p->data << " ";
cout << endl;
}
void List::print(Node *hd,int i){
for(Node *p = hd; p != NULL && p->next != NULL; p=p->next)
cout << p->data << " ";
cout << endl;
}
//非递归反转链表
List::Node* List::reverse(List::Node *head){
Node* p,*q,*tmp;//使用p和q两个指针配合工作,使得两个节点间的指向反向,同时用r记录剩下的链表
p = head->next;
q = NULL;
head->next = NULL;//旧的头指针是新的尾指针,next需要指向NULL
while(p){
tmp = p->next;//先保留下一个step要处理的指针
p->next = q;//然后p和q交替工作进行反向
q = p;
p = tmp;
}
head->next = q;//tmp为NULL,head->next指向最后一个节点q,就反转过来了.
return head;
}
//递归反转
List::Node* List::recursive_reverse(List::Node* hd){
//链表为空直接返回,而H->next为空是递归基
if(hd == NULL || hd->next == NULL){
//cout << "----hd:"<<hd<<" hd->next:"<<hd->next<<endl;
return hd;
}
//cout << "====hd:"<<hd<<" hd->next:"<<hd->next<<endl;
Node* new_hd=recursive_reverse(hd->next);//一直循环到链尾
//cout << "hd:"<<hd<<" hd->next:"<<hd->next<<endl;
//cout << "hd:"<<hd<<" hd->next->next:"<<hd->next->next<<endl;
//cout <<"data222: "<<hd->next->data << endl;
hd->next->next = hd;//本来hd->next->next=0x00为尾节点,现在hd->next->next = hd,指向head->next上一个节点.
//cout << "hd:"<<hd<<" hd->next:"<<hd->next<<" hd->next->next:"<<hd->next->next<<endl<<endl;
hd->next=NULL;//hd->next后节点为NULL,即尾节点,尾节点不断向前移动.
return new_hd;//新链表头永远指向的是原链表的链尾
}
int main(int argc, const char * argv[])
{
List list;
List::Node *new_head;
cout << "链表反转前:";
new_head = list.insert(5);
list.print(new_head);
cout << "链表反转后:";
new_head = list.reverse(new_head);
list.print(new_head);
cout << "链表反转后:";
new_head = list.recursive_reverse(new_head);
list.print(new_head,0);
return 0;
}