//用三种方法实现 单链表只遍历一次实现元素反转
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
int data;
struct node *next;
}node,* Linklist;
void print(Linklist &L)
{
Linklist p;
p = L;
p = p->next;
while(p)
{
printf("%2d",p->data);
p = p->next;
}
}
void create(Linklist &L,int len,int array[])
{
Linklist s,p;
p = L;
//p = p->next;
//p->data = array[0];//没有头结点的话,用这种写法比较好,先把第一个元素给首元结点
for(int i=0;i<len;i++)
{
//p->data = array[i];
s = (Linklist)malloc(sizeof(node));
s->data = array[i];
p->next = s;
p = s;
s->next = NULL;
}
print(L);
printf("\n");
}
//重新建立一个链表,用头结点插入法
void inverse(Linklist &L,int len)
{
Linklist h,p,s;
p = L->next;
h = (Linklist)malloc(sizeof(node));
h->next = NULL;
for(int i=0;i<len;i++)
{
s = (Linklist)malloc(sizeof(node));
s->data = p->data;
p = p->next;
s->next = h->next;
h->next = s;
}
L = h ;
}
//在原表上使用头结点插入法
void inverse1(Linklist &L,int len)
{
Linklist p,c,f,s;
c = L->next->next;//当前结点
p = L->next;//当前结点的前一结点
f = c->next;//当前结点的后一结点
s = p;
s->next = NULL;//将第一个结点的后继置为空,因为逆置后它是最后一个结点
while(c!=NULL)
{
c->next = L->next;
L->next = c;
p = c;
c = f;
if(f!=NULL)
f = f->next;
}
}
//反转指针指向法
void inverse2(Linklist &L,int len)//preview:当前结点的前一结点
{ //current:当前结点
Linklist preview,current,follow;//follow:当前结点的后一结点
preview = L->next;
current = preview->next;
follow = current->next;
while(current!=NULL)
{
current->next = preview; //当前结点指向它的前一结点
preview = current;
current = follow;
if(follow!=NULL)
follow = follow->next;
}
L->next->next = NULL;
L->next = preview;
}
int main()
{
int array[] = {1,2,3,4,5,6};
int len = sizeof(array)/sizeof(int);
Linklist L = (Linklist)malloc(sizeof(node));
create(L,len,array);
inverse(L,len);//重新建立一个链表,用头结点插入法
//inverse1(L,len);//在原表上使用头结点插入法
//inverse2(L,len);//反转指针指向法
print(L);
printf("\n");
return 0;
}