旋转链接列表

时间:2011-02-20 14:51:11

标签: 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!=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 个答案:

答案 0 :(得分:1)

您的链接列表实际上有4个元素。

您应该更改此行:

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

为:

for(i = length - 1; i >= 0; i--) {

因为前一行你要离开数组(你在第一次迭代时访问arr[length])。

通过此更改,您的rotate功能可以正常运行。

答案 1 :(得分:1)

你可以通过将它们分解为更简单的问题来解决大多数问题。

在这里,我按如下方式编写你的旋转:

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

答案 2 :(得分:0)

您的问题的问题是列表是向后存储的,并且您有指向之前的指针,而不是 next 。这应该是问题的一部分(我花了一些时间来理解这一点)。

实际上,当 tail 可能更好时,你可以使用 head 。您应该考虑存储指向实际 head 的指针,并避免这种方式复制。在这种情况下,您只需要调整指针。如果旋转将是一项常见任务,那么保留和更新额外的指针可能在列表结构中,将付出努力(可以将任务从O(n)更改为O(1 ))。

struct _list {
    node * tail;
    node * head;
};

typedef struct _list list;

在任何情况下,你的旋转功能的问题在于你是在同一个节点上以walk和prev开头的。

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

答案 3 :(得分:0)

我已经用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;
    }  
}

在链接列表d1的main方法中将k作为参数传递。

d1.rotateByk(1);

如果您有任何疑问,请与我们联系。