Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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 如何在双链接列表中正确使用方向开关?_C_Big O_Doubly Linked List - Fatal编程技术网

C 如何在双链接列表中正确使用方向开关?

C 如何在双链接列表中正确使用方向开关?,c,big-o,doubly-linked-list,C,Big O,Doubly Linked List,我有一个双链接列表,我想改变列表的方向。例如: 1->2->3 变成 3->2->1 我在结构中使用了布尔表达式来确定方向 typedef struct Node Node; struct Node { char character; Node *link[2]; bool dir; } direction; 我用这种格式确定方向: Node *p; p->link[p->dir]; 或 我遇到的问题是,我想用一个运行时为O(1)的方法来翻转这些布尔方向。我尝试构建一个函数,它

我有一个双链接列表,我想改变列表的方向。例如:

1->2->3

变成

3->2->1

我在结构中使用了布尔表达式来确定方向

typedef struct Node Node;

struct Node {
char character;
Node *link[2];
bool dir;
} direction;
我用这种格式确定方向:

Node *p;
p->link[p->dir];

我遇到的问题是,我想用一个运行时为O(1)的方法来翻转这些布尔方向。我尝试构建一个函数,它可以像这样处理它:

//global variable
int d = 0;

//function
void switchStack ( ) {
    if (d == 0) {
        d = 1;
        direction->link[direction->dir] = direction->link[!direction->dir];
    else if (d == 1) {
        d = 0;
        direction->link[direction->dir] = direction->link[!direction->dir];
    }

这个函数似乎不起任何作用,当我调用它时,我尝试的任何其他变体都会使程序崩溃。有没有人知道如何正确使用方向开关来反转运行时间为0(1)的堆栈?

这是我/最上面的注释的开头

我还是不确定你到底想要什么。但是,这是我能猜到的最接近的

listadd
始终附加到列表的尾部(即忽略
dir

但是,
listprint
尊重
dir
。它是您可能编写的其他函数的模型

但是,我认为只有
listprint
需要查看
dir
。所有其他函数都可以将给定列表视为转发列表(即查看
listadd
的工作原理)


为什么要将
dir
放入节点本身?使用DLink列表,您可以将
dir
作为参数传递给所有遍历函数,而不需要在每个节点中翻转它[这看起来很浪费,也不必要]?你到底想干什么?如果您想传递“自我描述”的列表,我会创建一个列表结构(例如,
typedef struct list{Node*head;Node*tail;int dir;}list
,并放置方向标志there@CraigEstey我正在尝试创建一个函数,它将完全翻转链表的顺序,或者翻转堆栈。我想找到一种方法,使用一个函数使堆栈在运行时为O(1)时翻转。你说的“你不需要翻转每个节点”是什么意思?你的代码用O(n)翻转。使用列表结构,您只需执行
list->dir=!list->dir
获取O(1)。看起来你真的不想改变链接指针???无论您是向前(例如
head
tail
)还是向后(例如
tail
head
),CraigEstey我确实想更改链接指针的表示形式。例如,当使用函数时,我希望true变为false,反之亦然。但老实说,我很难看到双链表的情况,当您只想选择遍历顺序时,节点的任何重新排序实际上都是必要的。如果这不是您想要的,我认为您必须真正考虑您需要什么,您可以修改我发布的内容,或者重写您现有的代码。
//global variable
int d = 0;

//function
void switchStack ( ) {
    if (d == 0) {
        d = 1;
        direction->link[direction->dir] = direction->link[!direction->dir];
    else if (d == 1) {
        d = 0;
        direction->link[direction->dir] = direction->link[!direction->dir];
    }
#include <stdio.h>
#include <stdlib.h>

typedef struct node Node;
struct node {
    Node *links[2];
    int value;
};
#define PREV    0
#define NEXT    1

typedef struct {
    Node *begend[2];
    int dir;
} List;
#define HEAD    0
#define TAIL    1

static inline Node *
listfirst(List *list)
{
    return list->begend[list->dir ? TAIL : HEAD];
}

static inline Node *
listlast(List *list)
{
    return list->begend[list->dir ? HEAD : TAIL];
}

static inline Node *
nodenext(List *list,Node *cur)
{
    return cur->links[list->dir ? PREV : NEXT];
}

static inline Node *
nodeprev(List *list,Node *cur)
{
    return cur->links[list->dir ? NEXT : PREV];
}

List *
listnew(void)
{
    List *list = calloc(1,sizeof(List));

    return list;
}

Node *
nodenew(int value)
{
    Node *cur = calloc(1,sizeof(Node));

    cur->value = value;

    return cur;
}

void
listadd(List *list,int value)
{
    Node *node = nodenew(value);
    Node *prev = list->begend[TAIL];

    do {
        if (prev != NULL) {
            prev->links[NEXT] = node;
            node->links[PREV] = prev;
            break;
        }

        list->begend[HEAD] = node;
    } while (0);

    list->begend[TAIL] = node;
}

void
listprint(List *list)
{
    Node *cur;

    for (cur = listfirst(list);  cur != NULL;  cur = nodenext(list,cur))
        printf("%d\n",cur->value);
}

int
main(void)
{
    List *list = listnew();

    listadd(list,1);
    listadd(list,2);
    listadd(list,3);

    printf("\n");
    printf("list in forward direction\n");
    listprint(list);

    // reverse the list
    list->dir = ! list->dir;

    printf("\n");
    printf("list in reverse direction\n");
    listprint(list);

    return 0;
}
list in forward direction
1
2
3

list in reverse direction
3
2
1