NOTE:需要说明的是:在本例中创建的链表是包含头结点的,对销毁来说每个结点都要销毁,所以无所谓该链表是不是
包含头结点,打印链表也是针对包含头结点的,也就是说在打印的时候没有打印头结点的data,实验证明头结点 的data是一个绝对值很大的异常值,也就是未赋值情况下的随机值。
对逆置来说,不管初始链表是不是包含头结点,逆置完后的链表都不含头结点,原链表的头结点(如果有的话)作为 最后一个结点,原来最后一个结点作为第一个结点,该结点不能成为头结点,因为这个结点有有意义的数据,当用本例中的打印函数输出逆置后的链表data时。比如原包含头结点的链表的结点值为:1 2 3 4 5,逆置后的打印本来认为应该是5 4 3 2 1,但由于本例中的打印函数是从头结点的下一个节点开始打印,所以就会发现输出的是:4 3 2 1 -987453212,最后一个其实是个未赋值的内存空间。
所以一定要注意是否包含头结点!!!
#include <iostream>
using namespace std;
typedef struct _node
{
int data;
struct _node *next;
}node;
//销毁链表
bool Destroy(node **head)
{
cout<<"Destroy begin----"<<endl;
if (NULL == *head)
{
cerr<<"link is null!"<<endl;
cout<<"Destroy over----"<<endl;
return false;
}
//销毁从头结点开始销毁
while (*head != NULL)
{
node *q = (*head)->next;
free(*head);
*head = q;
}
*head = NULL;
head = NULL;
cout<<"Destroy over----"<<endl;
return true;
}
//创建链表
node* Create()
{
node *head = NULL;
node *p = NULL;
node *s = NULL;
head = (node*)malloc(sizeof(node)); //创建头结点,头结点的data未赋值
if (NULL == head)
{
cerr<<"create error!"<<endl;
return NULL;
}
p = head;
int num = 0;
cout<<"please intput:";
while (cin >> num)
{
if (num != 0)
{
s = (node *)malloc(sizeof(node));
if (NULL == s)
{
Destroy(&head); //如果某一新结点分配失败则销毁该链表
return head;
}
else
{
s->data = num;
p->next = s;
p = s;
}
}
else
{
break;
}
}
p->next = NULL;
return head;
}
//打印链表
void Print(node *head)
{
if (NULL == head)
{
cerr<<"head is null!"<<endl;
return;
}
node *p = head->next; //从头结点下一个结点开始打印
cout<<"print link:";
while (p != NULL)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
}
//链表逆置
node* Reverse(node *head)
{
node *p1, *p2, *p3;
if (NULL == head || NULL == head->next)
{
cout<<"link is null"<<endl;
return head;
}
p1 = head;
p2 = p1->next;
while (p2 != NULL)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
head->next = NULL;
head = p1; //头指针指向原链表最后一个结点
return head;
}
int main()
{
node *head = Create();
cout<<head->data<<endl; //打印头结点data
Print(head); //打印链表
node *head2 = Reverse(head);
Print(head2);
Destroy(&head2);
Print(head2);
cout<<endl;
return 0;
}