在双向链表

时间:2017-10-21 20:33:26

标签: c linked-list nodes

我有一个双重链表,让我们说它是这样的:

typedef struct node {
  int data;
  node_t *prev, *next;
} node_t;

它已被设置,推送到等等。假设它包含20个值。

node_t *foo = malloc(sizeof(node_t));   // the actual list
for (int i = 0; i < 20; i++)
    push(&foo, i+1);

我还有一些代码可以让我的列表达到某一点。让我们说它得到索引12:

for (int i = 0; i < 12; i++)
    foo = foo->next;

现在我想在列表中的当前位置插入一个节点。所以目前我的名单是这样的:

index: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19
value: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
                                              ^ current position

在这里插入一个带有值8的节点,应将其转换为:

index: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
value: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 8,  13, 14, 15, 16, 17, 18, 19, 20
                                              ^ current position

我正在使用它来插入节点(排除错误检查):

void insert_at_start(node_t **head, int val)
{
    node_t *newnode = malloc(sizeof(node_t));

    newnode->data = val;
    newnode->next = (*head);
    (*head) = newnode;
}

但是,这不会保留当前位置左侧的任何数据;只有在右边。它将列表转换为:

index: 0, 1,  2,  3,  4,  5,  6,  7,  8
value: 8, 13, 14, 15, 16, 17, 18, 19, 20
       ^ current position

如何修改insert_at_start(将其更改为insert_at_current),以便保留列表的左侧,而不假设我知道列表的索引是什么?

3 个答案:

答案 0 :(得分:2)

假设您当前的位置是索引11处的节点。

您希望在索引11和索引12之间插入。  假设head指向索引11处的节点。

  void insert_at_start(node_t **head, int val)
    {
        node_t *newnode = malloc(sizeof(node_t));

        newnode->data = val;

        //insert between two node eg. node 11 and 12
        node_t *n_11 = *head;        // node 11
        node_t *n_12 = (*head)->next; // node 12

        n_11->next = newnode;
        n_12->prev = newnode;

        newnode->next = n_12;
        newnode->prev = n_11;

        (*head) = newnode;
    }

答案 1 :(得分:0)

使用来自Jonathan Leffler的help计算出来,实施here

void add_at_current(token_t **current, int val)
{
    if (!(*current)) {
        (*current) = malloc(sizeof(token_t));
        (*current)->val = val;
        (*current)->next = NULL;
        (*current)->prev = NULL;
        return;
    }

    token_t *newnode = malloc(sizeof(token_t));

    newnode->val = val;
    newnode->prev = (*current)->prev;
    (*current)->prev = newnode;
    newnode->prev->next = newnode;
    newnode->next = (*current);
}

答案 2 :(得分:-1)

对insert_at_start的代码进行最小的更改

void insert_at_current(node_t **head, int index, int val)
{   
  node_t *newnode = malloc(sizeof(node_t));

  node_t *current = *head;
  for (int i = 0; i < index; i++) //bring current to the point where you need it to
     current = current ->next;

  newnode->next = current->next; //set the next of the new node
  newnode->prev = current; //set the prev of the new node
  newnode->data = val;
  current->next->prev=newnode //set the prev of the node after the one we insert
  current->next=newnode; //set the next of the current node


}

此外,正如评论中指出的那样,你不应该忘记将newnode的prev设置为null,并且list的prev在insert_at_start函数中转到newnode