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

//用三种方法实现  单链表只遍历一次实现元素反转


#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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值