编程之美(一)单链表只遍历一次实现元素反转

来源:互联网 发布:unity3d往复运动 编辑:程序博客网 时间:2024/05/01 08:55
//用三种方法实现  单链表只遍历一次实现元素反转
#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;}