回 帖 发 新 帖 刷新版面

主题:逆置链表算法请教(请尽可能使算法高效率)

写一个算法,对一带头结点且仅设队尾指针的链式循环队列就地逆置.
(即队头变队尾,队尾变队头)

链队头的结点结构定义如下:
typedef struct Qnode{
Qelemtype data;
struct Qnode,*next;
}Qnode,*LinkQueue;

回复列表 (共6个回复)

沙发

建立一个新队列
原队从队尾开始出列
取出的元素放入新队列
最后原队列为空后返回新队列

板凳

楼上的做法错误

3 楼

p=L->next;L->next=NULL;
while(p)
{
  s=p;
  p=p->next;
  s->next=L->next;
  L->next=s;
}

4 楼

[quote]楼上的做法错误[/quote]
我想问的是哪错了?
所有的逆置最基本的想法就是改变指针的顺序
我把所有的元素取出来按照逆序重排这种方法你可以说效率有限,但是绝对不是错的!

5 楼

给你找到了下述资料:
问题描述:给定一个单向链表,如何进行倒置
思路1:从表头走下去,逐个next指针向回指,中间要注意不能把下一个节点丢掉。
       所以循环里面应该随时保证有三个节点的存在.
思路2:使用栈将节点完全存入,然后逐个弹出,在弹出的过程中对next指针赋值。
       这里程序写了两种解决方案a.自定义栈类 b.使用STL的栈
思路3: 使用递归程序解决。节点数为N的倒叙策略实际上相当于去掉头节点后的N-1的倒序再把头补在尾部。
程序如下:
// ReverseLinkList.cpp 
//
#include "stdafx.h"
#include<iostream>
#include<stack>
using namespace std;
class LinkNode
{
public:
 int number;
 LinkNode * next;
};
class StackNode
{
public:
 LinkNode * data ;
 StackNode * next;
};
class Stack
{
 //自定义的栈类
public:
 StackNode * top ;
   int size ; 
public:
 Stack()
   {
   top = NULL;
   size = 0 ;
   }
   void push(LinkNode * node)
   {
    if(size ==0 )
    {
     top = new StackNode;
     top->data = node;
     top->next = NULL;
     
    }
    else
    {
          StackNode * temp = new StackNode;
    temp->data = node;
    temp->next = top;
    top = temp;
    }
    size ++;
   }
   LinkNode* pop()
   {
     StackNode * temp = top;
  LinkNode* returnData = NULL;
  top = top->next;
  size --;
  returnData=temp->data;
  delete temp;
  return returnData;
   }
};
LinkNode * createLinkList()
{
 //建立链表的过程,用于测试
 LinkNode * head = new LinkNode;
 LinkNode * last = head;
 head->number = 0 ;
 for( int i = 1 ; i<=4 ; i++)
 {
  LinkNode * temp = new LinkNode;
  temp->number = i ;
  temp->next = NULL;
  last->next = temp;
  last = temp;
 }
 return head;
}
LinkNode * reverseLinkList1(LinkNode * head)
{
   //倒序链表,递归方案
 LinkNode * myHead = head;
    LinkNode * returnHead =NULL;
 LinkNode * t1 = myHead->next;
 if(t1->next != NULL)
 {
  returnHead = reverseLinkList1(t1);
     t1->next = myHead;
  myHead->next = NULL;
   
 }
 else
 {
  t1->next = myHead;  
        return t1;
 }
 return returnHead;
}
LinkNode * reverseLinkList(LinkNode * head)
{
 //倒序链表 , 思路一,直接循环
   
 LinkNode * t1 = head;
 LinkNode * t2 = head->next;
 LinkNode * t3 = t2->next;;
 head ->next = NULL;
 while (t3!=NULL)
 {
  t2->next = t1;
  t1= t2;
  t2 = t3;
  t3 = t3->next;
 }
 t2->next = t1;
 
 return  t2;
}
void countList(LinkNode * head)
{
 //遍历链表,用于测试
 LinkNode * temp = head;
 while (temp!=NULL)
 {
  cout<<temp->number<<"------>";
  temp = temp->next;
 }
 cout<<endl;
}
LinkNode * reverseLinkList2(LinkNode * head)
{
 //倒序链表,自定义栈的解决方案
 Stack a ;
 LinkNode * temp  = head;
    while(temp!=NULL)
 {
  a.push(temp);
  
  temp=temp->next;
 }
 LinkNode * returnHead = temp = a.pop();
 while(a.size>0)
 {
  temp->next = a.pop(); 
  temp = temp->next;
 }
 temp->next = NULL;
 return returnHead;
}
LinkNode * reverseLinkList3(LinkNode * head)
{
 //倒序链表,系统栈的解决方案
 std::stack<LinkNode*> s;
 LinkNode * temp  = head;
    while(temp!=NULL)
 {
  //a.push(temp);
  s.push(temp);
  temp=temp->next;
 }
 LinkNode * returnHead = temp = s.top();
 s.pop();
 while(!s.empty())
 {
  temp->next = s.top(); 
  s.pop();
  temp = temp->next;
 }
 temp->next = NULL;
 return returnHead;
}
int _tmain(int argc, _TCHAR* argv[])
{
 //测试用主函数
 LinkNode * head = NULL;
 LinkNode * newhead = NULL;
 head = createLinkList();
 countList(head);
 newhead = reverseLinkList3(head);
 cout<<"****************hahaha*****************"<<endl;
    countList(newhead);
 
 return 0;
}
////我的方法是第二种思路

6 楼

遍历链表,顺序取出节点,插入新表的表头位置
应该是最直接有效的方法了

void reverve(LinkQueue *L)
{
    LinkQueue p,q,tmp=NULL;
    if(*L==NULL) return;
    for(q=*L,p=q->next;p!=NULL;q=p,p=p->next)
    {
        q->next=tmp;
        tmp=q;
    }
    *L=q;
}
    
有没有头节点都不影响算法,没头节点你就调用
reverse(&L);
有头节点你就调用
reverse(&(L->next));

我来回复

您尚未登录,请登录后再回复。点此登录或注册