C 旋转链接列表

C 旋转链接列表,c,C,我想旋转包含数字的链表。123应旋转为231。函数创建了23,但最后一个字符保持为空,为什么 typedef struct node node; struct node{ char digit; node* p; }; void rotate(node** head){ node* walk= (*head); node* prev= (*head); char temp= walk->digit; while(walk->p

我想旋转包含数字的链表。123应旋转为231。函数创建了23,但最后一个字符保持为空,为什么

typedef struct node node;  
struct node{
    char digit;
    node* p;
};

void rotate(node** head){

    node* walk= (*head);
    node* prev= (*head);
    char temp= walk->digit;

    while(walk->p!=NULL){

        walk->digit=walk->p->digit;

        walk= walk->p;
        }

    walk->digit=temp;
}
如何创建列表:

node* convert_to_list(int num){ 
   node * curr, * head;

   int i=0,length=0; 

   char *arr=NULL;

   head = NULL;

   length =(int) log10(((double) num))+1;
   arr =(char*) malloc((length)*sizeof(char));          //allocate memory 

   sprintf (arr, "%d" ,num); //(num, buf, 10);

    for(i=length;i>=0;i--) {
      curr = (node *)malloc(sizeof(node));
      (curr)->digit =  arr[i];
      (curr)->p = head;
      head = curr;
   }

   curr = head;

   return curr;
}

你的链表实际上有4个元素

您应该更改此行:

for(i = length; i >= 0 ; i--) {
致:

因为对于前一行,您将退出数组(在第一次迭代中访问
arr[length]


通过此更改,您的
旋转
功能可以正常工作。

您的问题在于列表是向后存储的,并且您有一个指向“上一个”的指针,而不是指向“下一个”。这本应该是问题的一部分(我花了一段时间才明白这一点)

事实上,你用头的时候尾巴可能会更好。您应该考虑将指针存储到实际的头上,避免这种方式复制。在这种情况下,您只需要调整指针。如果轮换将是一项常见的任务,那么保留和更新一个额外的指针,可能位于列表中结构中,将付出努力(可以将任务从O(n)更改为O(1))

在任何情况下,旋转函数的问题在于,您在同一节点“头”上开始使用“行走”和“上一步”

void rotate(node** head){
    node* walk= (*head);
    node* prev=(*head)->p;
    char temp= walk->digit;

    while(prev!=NULL){

        walk->digit=prev->digit;

        walk= prev;
        prev = prev->p;
    }

    walk->digit=temp;
}

你可以把大多数问题分解成简单的问题来解决

在这里,我将写下你的轮换如下:

void rotate(node **list) {
    node *head = pop_head(list);
    push_at_end(list, head);
}

node *pop_head(node **list) {
    assert(*list);
    node *head = *list;
    *list = head->p;
    head->p = 0;
    return head;
}

void push_at_end(node **list, node *head) {
    node *end = get_end(*list);
    if (!end) {
        *list = head;
    } else {
        end->p = head;
    }
}

node *get_end(node *head) {
    node *last = 0;
    while (head) {
        last = head;
        head = head->p;
    }
    return last;
}

<>我用C++中的k节点编写了链表旋转代码。它对我非常有效。如果将k传递为1,它将把喜欢的列表旋转1个节点,在这里它解决了给定的问题。如果要将链表旋转k个节点,它仍然可以正常工作。请在下面找到

头文件:

public:
typedef struct node {

    int data;
    node *next; 

} *Node;

Node head;
void rotateByk(int k);
以下代码用于.cpp文件

void DList::rotateByk(int k){
    Node current = head;
    Node kthNode;
    int count = 1;
    while(count<=k && current!=NULL){
        kthNode = current;
        current = current->next;
        count++;
    }

    Node kthNextNode = current;

    while(current->next!=NULL){
        current = current->next;
    }

    current->next = head;
    head = kthNextNode;
    kthNode->next = NULL;

    Node printNode = head;
    while(printNode!=NULL){
        cout << printNode->data << "\t";
        printNode = printNode->next;
    }  
}

如果您有任何疑问,请告诉我。

您的轮换代码似乎在移动数字,而不是重新链接列表,我认为这是练习的目的。对于等效的解决方案,您会得到一些分数,但这可能不是您应该演示的技术。您需要再分配一个字节—您的
sprintf()
超出了分配的空间。你的长度是3,数字是123;您还需要分配一个空终止符。这一次你可以侥幸逃脱,因为
malloc()
可能会分配至少8个字节的倍数,但这是一种不好的做法,如果你没有分配足够的空间,你迟早会被烧掉。但是我应该能够返回一个指向新节点的指针。旋转原型必须是这样的。什么是“向后”,或者你确定吗?数字(3)的最后一位存储在最后一个节点中,因为构造循环倒计时(索引2、1、0)而不是倒计时(索引0、1、2)格式化字符串-给出或接受原始错误。向后表示从“最后”到“第一”读取项目,特别是考虑到头指针指向“最后”元素,即本例中的3或2。
public:
typedef struct node {

    int data;
    node *next; 

} *Node;

Node head;
void rotateByk(int k);
void DList::rotateByk(int k){
    Node current = head;
    Node kthNode;
    int count = 1;
    while(count<=k && current!=NULL){
        kthNode = current;
        current = current->next;
        count++;
    }

    Node kthNextNode = current;

    while(current->next!=NULL){
        current = current->next;
    }

    current->next = head;
    head = kthNextNode;
    kthNode->next = NULL;

    Node printNode = head;
    while(printNode!=NULL){
        cout << printNode->data << "\t";
        printNode = printNode->next;
    }  
}
d1.rotateByk(1);