Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 反转链表的每k个节点_C_Algorithm_Linked List - Fatal编程技术网

C 反转链表的每k个节点

C 反转链表的每k个节点,c,algorithm,linked-list,C,Algorithm,Linked List,我正在准备一次技术面试,我一直在写这个程序来反转链表中的每个k节点 比如说 1->2->3->4->5->6 //Linked List 2->1->4->3->6->5 //Output for k=2 编辑: 这是我的密码。我只得到6->5作为输出 struct node* recrev(struct node* noode,int c) { struct node* root=noode,*temp,*final,*prev=

我正在准备一次技术面试,我一直在写这个程序来反转链表中的每个k节点

比如说

1->2->3->4->5->6 //Linked List
2->1->4->3->6->5 //Output for k=2
编辑:

这是我的密码。我只得到6->5作为输出

struct node* recrev(struct node* noode,int c)
{
 struct node* root=noode,*temp,*final,*prev=NULL;
 int count=0;
 while(root!=NULL && count<c)
 {
  count++;
  temp=root->link;
  root->link=prev;
  prev=root;
  root=temp;
 }
 if(temp!=NULL)
   noode->link=recrev(temp,c);
 else
   return prev;

}
struct node*recrev(struct node*noode,int c)
{
结构节点*root=noode,*temp,*final,*prev=NULL;
整数计数=0;
while(root!=NULL&&countlink;
root->link=prev;
prev=根;
根=温度;
}
如果(温度!=NULL)
noode->link=recrev(温度,c);
其他的
返回上一个;
}
谢谢你的帮助,谢谢

编辑:我试图实现Eran Zimmerman的算法,如下所示

struct node* rev(struct node* root,int c)
{
 struct node* first=root,*prev,*remaining=NULL;
 int count=0;
 while(first!=NULL && count<c)
 {

    count++;
    prev=first->link;
    first->link=remaining;
    remaining=first;
    first=prev;
 }
 return remaining;
}
struct node* recc(struct node* root,int c)
{
 struct node* final,*temp,*n=root,*t;
 int count=0;
 while(n!=NULL)
 {
       count=0;
       temp=rev(n,c);
       final=temp;


    while(n!=NULL && count<c)
    {   
     printf("inside while: %c\n",n->data);  // This gets printed only once
     if(n->link==NULL) printf("NULL");    //During first iteration itself NULL gets printed
        n=n->link;
        final=final->link;
        count++;
    }

 }
 final->link=NULL;
 return final;
}
struct node*rev(struct node*root,int c)
{
结构节点*first=root,*prev,*remaining=NULL;
整数计数=0;
while(first!=NULL&&countlink;
第一->链接=剩余;
剩余=第一;
第一个=上一个;
}
返回剩余值;
}
结构节点*recc(结构节点*root,int c)
{
结构节点*final,*temp,*n=root,*t;
整数计数=0;
while(n!=NULL)
{
计数=0;
温度=转速(n,c);
最终=温度;
while(n!=NULL&&countdata);//只打印一次
如果(n->link==NULL)printf(“NULL”);//在第一次迭代过程中,会打印NULL
n=n->link;
最终=最终->链接;
计数++;
}
}
final->link=NULL;
返回最终结果;
}

我会这样做:

init curr (node pointer) to point to the beginning of the list.
while end of list is not reached (by curr):
- reverse(curr, k)
- advance curr k times
reverse是一个函数,它从curr开始反转前k个元素

这可能不是最优雅或最有效的实现,但它可以工作并且非常简单

要回答有关您添加的代码的问题,请执行以下操作:


您返回了prev,它一直处于高级状态。您应该返回列表的开头。

我喜欢您使用递归,尽管它可能不是最佳解决方案。我可以从您的代码中看出,您在设计它时会深入思考。您离答案只有一步之遥

原因:在递归情况下,您忘记返回新的
根节点

if(temp!=NULL)
   noode->link=recrev(temp,c);
   // You need return the new root node here
   // which in this case is prev:
   // return prev;
 else
   return prev;
(我假设这是一个单链接列表。)您可以保留一个临时指针(我们称之为
nodek
),并在while循环中将其前进k次。这将需要O(k)。现在您有一个指向列表开头和子列表最后一个元素的指针。要在此处反转,请从head中删除O(1)并添加到
nodek
,即O(1)。对所有元素执行此操作,使其再次成为O(k)。现在将root更新为nodek,并再次在nodek上运行while循环(以获得
nodek
)并再次重复整个过程。记住在此过程中进行任何错误检查。 此解决方案将在O(n)处运行,只需要O(1)个额外空间。

下面是一个伪代码

temp = main_head = node.alloc ();
while ( !linked_list.is_empty () )
{
    push k nodes on stack
    head = stack.pop ();
    temp->next = head;
    temp = head;
    while ( !stack.empty () )
    {
        temp->next = stack.pop ();
        temp = temp->next;
    }
}
我已经做了这个代码的演示实现。请原谅这个混乱的实现。这将适用于
k
的任何值。每个
k
大小的段在内环中分别反转,不同的段在进入内环之前在外环中相互链接。
temp
跟踪最后的n
k
大小的子列表的ode和
head
保存下一个子列表的下一个值,我们将它们链接起来。使用显式堆栈进行反转

#include <stdio.h>
#include <stdlib.h>

typedef struct _node {
  int a;
  struct _node *next;
} node_t;

typedef struct _stack {
  node_t *arr[128];
  int top;
} stack_t;

void stk_init (stack_t *stk)
{
  stk->top = -1;
}

void push (stack_t *stk, node_t *val)
{
  stk->arr[++(stk->top)] = val;
}

node_t *pop (stack_t *stk)
{
  if (stk->top == -1)
   return NULL;
  return stk->arr[(stk->top)--];
}

int empty (stack_t *stk)
{
  return (stk->top == -1);
}

int main (void)
{
  stack_t *stk = malloc (sizeof (stack_t));
  node_t *head, *main_head, *temp1, *temp;
  int i, k, n;

  printf ("\nEnter number of list elements: ");
  scanf ("%d", &n);
  printf ("\nEnter value of k: ");
  scanf ("%d", &k);

  /* Using dummy head 'main_head' */
  main_head = malloc (sizeof (node_t));
  main_head->next  = NULL;
  /* Populate list */
  for (i=n; i>0; i--)
  {
    temp = malloc (sizeof (node_t));
    temp->a = i;
    temp->next = main_head->next;
    main_head->next = temp;
  }

  /* Show initial list */
  printf ("\n");
  for (temp = main_head->next; temp != NULL; temp = temp->next)
  {
    printf ("%d->", temp->a);
  }

  stk_init (stk);

  /* temp1 is used for traversing the list
   * temp is used for tracing the revrsed list
   * head is used for tracing the sublist of size 'k' local head
   * this head value is used to link with the previous
   * sublist's tail value, which we get from temp pointer
   */
  temp1 = main_head->next;
  temp = main_head;
  /* reverse process */
  while (temp1)
  {
    for (i=0; (temp1 != NULL) && (i<k); i++)
    {
      push (stk, temp1);
      temp1 = temp1->next;
    }
    head = pop (stk);
    temp->next = head;
    temp = head;
    while (!empty (stk))
    {
      temp->next = pop (stk);
      if (temp->next == NULL)
        break;
      temp = temp->next;
    }
  }
  /* Terminate list with NULL . This is necessary as
   * for even no of nodes the last temp->next points
   * to its previous node after above process
   */
  temp->next = NULL;

  printf ("\n");
  for (temp = main_head->next; temp != NULL; temp = temp->next)
  {
    printf ("%d->", temp->a);
  }

  /* free linked list here */

  return 0;
}
#包括
#包括
类型定义结构节点{
INTA;
结构_节点*下一步;
}节点t;
typedef结构栈{
节点_t*arr[128];
int top;
}堆叠;
void stk_init(堆栈*stk)
{
stk->top=-1;
}
无效推送(堆栈*stk,节点*val)
{
stk->arr[++(stk->top)]=val;
}
节点\u t*pop(堆栈\u t*stk)
{
如果(stk->top==-1)
返回NULL;
返回stk->arr[(stk->top)--];
}
int空(堆栈*stk)
{
返回(stk->top==-1);
}
内部主(空)
{
stack_t*stk=malloc(sizeof(stack_t));
节点头、*主头、*temp1、*temp;
inti,k,n;
printf(“\n输入列表元素数:”);
scanf(“%d”和“&n”);
printf(“\n输入k的值:”);
scanf(“%d”和“&k”);
/*使用虚拟头“主头”*/
main_head=malloc(sizeof(node_t));
main_head->next=NULL;
/*填充列表*/
对于(i=n;i>0;i--)
{
temp=malloc(sizeof(node_t));
温度->a=i;
临时->下一步=主头->下一步;
主头->下一个=温度;
}
/*显示初始列表*/
printf(“\n”);
用于(临时=主头->下一步;临时!=NULL;临时=临时->下一步)
{
printf(“%d->”,temp->a);
}
stk_init(stk);
/*temp1用于遍历列表
*temp用于跟踪已撤销的列表
*head用于跟踪大小为“k”的局部head子列表
*此头值用于链接上一个头
*子列表的尾值,我们从临时指针获得
*/
temp1=主头->下一步;
温度=主压头;
/*反向过程*/
while(temp1)
{
对于(i=0;(temp1!=NULL)和(inxt;
}
水头=波普(stk);
温度->下一步=头部;
温度=水头;
而(!空(stk))
{
临时->下一步=弹出(stk);
如果(临时->下一步==NULL)
打破
温度=温度->下一步;
}
}
/*使用NULL终止列表。这是必要的,因为
*即使没有节点,最后一个临时->下一个点
*在完成上述过程后返回到其上一个节点
*/
temp->next=NULL;
printf(“\n”);
用于(临时=主头->下一步;临时!=NULL;临时=临时->下一步)
{
printf(“%d->”,temp->a);
}
/*这里有免费的链接列表*/
返回0;
}

是的,我从来都不喜欢递归,所以下面是我使用迭代的一次尝试:

  public Node reverse(Node head, int k) {
       Node st = head;
       if(head == null) {
         return null;
       }

       Node newHead = reverseList(st, k);
       st = st.next;  

       while(st != null) {
         reverseList(st, k);
         st = st.next;
       } 

       return newHead

  }


 private Node reverseList(Node head, int k) {

      Node prev = null;
      Node curr = head;
      Node next = head.next;

      while(next != null && k != 1){
       curr.next = prev;
       prev = curr;
       curr = next;
       next = next.next;
       --k;
      }
      curr.next = prev;

      // head is the new tail now.
      head.next = next;

      // tail is the new head now.
      return curr;
 }

下面的解决方案使用额外的空间来存储指针,并分别反转每个列表块。最后,构建了新的列表。当我测试时,这似乎涵盖了边界条件

template <typename T>
struct Node {
T data;  
struct Node<T>* next;
Node()  {  next=NULL; } 
};
template <class T>
void advancePointerToNextChunk(struct Node<T> * & ptr,int  & k)  {
int count =0;  
while(ptr && count <k )  {
    ptr=ptr->next; 
    count ++; 
}
k=count;}

/*K-Reverse Linked List */
template <class T>  
 void kReverseList( struct Node<T> * & head,  int k){ 
 int storeK=k,numchunk=0,hcount=0;
 queue < struct Node<T> *> headPointerQueue;  
 queue <struct Node<T> *>  tailPointerQueue; 

 struct Node<T> * tptr,*hptr;
 struct Node<T> * ptr=head,*curHead=head,*kReversedHead,*kReversedTail;
 while (ptr) {
 advancePointerToNextChunk(ptr,storeK);
 reverseN(curHead,storeK,kReversedHead,kReversedTail);
 numchunk++; 
 storeK=k; 
 curHead=ptr;
 tailPointerQueue.push(kReversedTail),headPointerQueue.push(kReversedHead); 
 }
 while( !headPointerQueue.empty() ||  !tailPointerQueue.empty() )  {
    if(!headPointerQueue.empty()) {
        hcount++;  
        if(hcount == 1) { 
            head=headPointerQueue.front(); 
            headPointerQueue.pop();
        }
        if(!headPointerQueue.empty()) {
        hptr=headPointerQueue.front(); 
        headPointerQueue.pop(); 
        }
    }
    if( !tailPointerQueue.empty() ) {
        tptr=tailPointerQueue.front();  
        tailPointerQueue.pop(); 
    }
    tptr->next=hptr;  
 }
 tptr->next=NULL;}

 template <class T> void reverseN(struct Node<T> * & head, int k, struct Node<T> * &   kReversedHead, structNode<T> * & kReversedTail ) {
  struct Node<T> * ptr=head,*tmp;  
  int count=0;
  struct Node<T> *curr=head,*nextNode,*result=NULL; 
  while(curr && count <k) {
      count++; 
      cout <<"Curr data="<<curr->data<<"\t"<<"count="<<count<<"\n"; 
      nextNode=curr->next;  
      curr->next=kReversedHead; 
      kReversedHead=curr;
      if(count ==1 )  kReversedTail=kReversedHead; 
      curr=nextNode;
  }}
模板
结构节点{
T数据;
结构节点*下一步;
Node(){next=NULL;}
};
模板
void advancePointerToNextChunk(结构节点*&ptr,int&k){
整数计数=0;
while(ptr&&countnext;
计数++;
}
k=计数;}
/*K-反向链表*/
模板
void kReverseList(结构节点*&头,int k){
int-storeK=k,numchunk=0,hcount=0;
队列headPointerQueue;
public class ReverseEveryKNodes<K>
{
      private static class Node<K>
      {
        private K k;
        private Node<K> next;

        private Node(K k)
        {
            this.k = k;
        }
      }
private Node<K> head;
private Node<K> tail;
private int size;

public void insert(K kk)
{
    if(head==null)
    {
        head = new Node<K>(kk);
        tail = head;
    }
    else
    {
        tail.next = new Node<K>(kk);
        tail = tail.next;
    }
    size++;
}

public void print()
{
    Node<K> temp = head;
    while(temp!=null)
    {
        System.out.print(temp.k+"--->");
        temp = temp.next;
    }
    System.out.println("");
}

public void reverse(int k)
{
    head = reverseK(head, k);
}

Node<K> reverseK(Node<K> n, int k)
{
    if(n==null)return null;

    Node<K> next=n, c=n, previous=null;
    int count = 0;
    while(c!=null && count<k)
    {
        next=c.next;
        c.next=previous;
        previous=c;
        c=next;
        count++;
    }
    n.next=reverseK(c, k);
    return previous;
}

public static void main(String[] args)
{
    ReverseEveryKNodes<Integer> r = new ReverseEveryKNodes<Integer>();
    r.insert(10);
    r.insert(12);
    r.insert(13);
    r.insert(14);
    r.insert(15);
    r.insert(16);
    r.insert(17);
    r.insert(18);
    r.print();
    r.reverse(3);
    r.print();
}
}