C 交换单链表中的节点

C 交换单链表中的节点,c,pointers,swap,singly-linked-list,C,Pointers,Swap,Singly Linked List,我正在尝试交换两个节点。例如,如果节点是a和b我正在传递指针 (a-1)->next和(b-1)->next基本上是节点a和b void swap(struct stack **a,struct stack **b) { struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b; *a = *b; (*b)->next = (temp1)->next; temp2 = temp1; (t

我正在尝试交换两个节点。例如,如果节点是
a
b
我正在传递指针
(a-1)->next
(b-1)->next
基本上是节点
a
b

void swap(struct stack **a,struct stack **b)
{
    struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b;      
    *a = *b; 
    (*b)->next = (temp1)->next;
    temp2 = temp1;
    (temp2)->next = temp3->next;
}
node[9] points to node[2]
node[6] points to node[5]     
我做错了什么?当我在调用函数后试图打印节点时,它是一个无限循环。请帮助。

为什么是无限循环?
node[9] points to node[2]
node[6] points to node[5]     
无限循环是因为调用
swap()
函数后列表中出现了自循环。在
swap()

(*b)->next = (temp1)->next; 
node[9] points to node[2]
node[6] points to node[5]     
为什么?:因为在
swap()
函数
temp1
中的赋值语句之后,下一个开始指向
b
节点。和
节点[b]
的下一个循环点。而自循环无限循环的原因,在代码中遍历链表的某个地方

node[9] points to node[2]
node[6] points to node[5]     
下面我画了一幅图,展示了
swap()
如何一步一步地工作。这可能有助于您理解错误:

node[9] points to node[2]
node[6] points to node[5]     
您没有提到,但我假设链表在
a
b
之间有以下关系:(阅读红色注释)

node[9] points to node[2]
node[6] points to node[5]     
(步骤1):

+----+----+----+      +---+----+----+
|      one     |----->|    two      |
+----+----+----+      +---+---+-----+
  ^     ^              ^    ^
  |     |              |    |
  |    *a              |   *b
  |                    | 
 temp1                temp2, temp3     "after assignment to temp variables"

(step-2):                   ^
                            | 
*a = *b                     | *a       "<--- next step"
node[9] points to node[2]
node[6] points to node[5]     
+---+    +---+    +---+    +---+    +---+                               
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+    +---+    +---+    +---+    +---+  |                                
 ^        ^                  ^            null  
 |        |                  | 
 |       (p)                (q)   
 (head) 
以下是我这两行的示意图:

temp2 = temp1;         
+----+----+----+      +---+----+----+ <---|
|      one     |      |    two      |-----|  "<--- Self loop"
+----+----+----+      +---+---+-----+
  ^                    ^    ^    ^
  |                    |    |    |
  |                    |   *b    *a
  |                    | 
  temp2 = temp1;      temp3  
node[9] points to node[2]
node[6] points to node[5]     
所以循环仍然存在于
two
节点,所以循环是无限的

node[9] points to node[2]
node[6] points to node[5]     
如何交换单链表中的两个节点? 一种方法是交换节点的数据,而不是交换节点在链表中的位置(正如我对您的问题的评论)。但是您想交换节点在列表中的位置。
好吧,这太好了!如果节点数据大小更大,那么最好交换节点的位置,而不是交换节点的数据(交换数据将是错误的选择)

node[9] points to node[2]
node[6] points to node[5]     
因为您有单链表,所以要交换列表中的任意两个节点,您也需要有以前的节点地址。(这是你在交换逻辑中不考虑的点)

node[9] points to node[2]
node[6] points to node[5]     
为什么需要前面的指针?
假设在一些成功的插入(推送)操作之后,您的列表如下所示:

 0  <--------TOP - "head"
 9  <--p  
 2    
 6  <--q           
 5  
node[9] points to node[2]
node[6] points to node[5]     
正如我所说,为了交换,我们需要前面的指针。您需要考虑以下内容
(理论上,我是为特定的节点
(p)
(q)
编写的,只是为了让解释更简单。但我的实现是通用的):

node[9] points to node[2]
node[6] points to node[5]     
在前面的指针列表中:

node[0] points to node[9] that is (q), and 
node[2] points to node[6] that is (p)
node[9] points to node[2]
node[6] points to node[5]     

node[9] points to node[2]
node[6] points to node[5]     
注意:如果要交换两个节点,如
节点[9]
节点[6]
,则应使用这两个节点之前的节点指针。
例如:两个交换
节点[9]
[6]
,您还需要更改上图中
节点[0]
的下一个指针和
节点[2]
的下一个指针

node[9] points to node[2]
node[6] points to node[5]     
交换这两个节点后,列表将如何显示?

+----+----+----+      +---+----+----+
|      one     |----->|    two      |
+----+----+----+      +---+---+-----+
  ^     ^              ^    ^
  |     |              |    |
  |    *a              |   *b
  |                    | 
 temp1                temp2, temp3     "after assignment to temp variables"

(step-2):                   ^
                            | 
*a = *b                     | *a       "<--- next step"
node[9] points to node[2]
node[6] points to node[5]     
+---+    +---+    +---+    +---+    +---+                               
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+    +---+    +---+    +---+    +---+  |                                
 ^        ^                  ^            null  
 |        |                  | 
 |       (p)                (q)   
 (head) 
以前的节点
[o]
[2]
中现在是什么?
交换后,在列表中列出以前的指针

node[9] points to node[2]
node[6] points to node[5]     
node[0] points to node[6] that is (q), and 
node[2] points to node[9] that is (p)      

node[9] points to node[2]
node[6] points to node[5]     
所以如果你想交换两个节点;前面的节点也会产生影响,因为列表是单链接列表,所以您也需要前面的指针

node[9] points to node[2]
node[6] points to node[5]     
如何查找以前的节点指针?

node[9] points to node[2]
node[6] points to node[5]     
假设要交换任意两个节点
节点[p]
节点[q]
,则可以使用
头指针
查找上一个节点

node[9] points to node[2]
node[6] points to node[5]     
因此交换函数语法(在我的实现中)如下所示:

node[9] points to node[2]
node[6] points to node[5]     
void swap(struct stack **head, // head node 
          struct stack **a,    // first candidate node to swap
          struct stack **b);   // first candidate node to swap
您将调用如下函数:

node[9] points to node[2]
node[6] points to node[5]     
swap(&head, &p, &q);
定义:(要理解代码,请阅读我在几乎每行添加的注释)

node[9] points to node[2]
node[6] points to node[5]     
swap()。此函数返回列表中上一个节点的地址。在函数
get_prevend(,)中,第一个参数是列表头,第二个参数是要查找的节点

node[9] points to node[2]
node[6] points to node[5]     
// find previous node function()
struct stack* get_prevnd(
                 struct stack* head, 
                 struct stack* a
                ){
    if(head == a){
        // node[a] is first node 
        return NULL;
    }
    struct stack* temp = head; // temp is current node
    struct stack* pre_a = NULL; 

    while(temp && temp!=a){ //search while not reach to end or the node
        pre_a = temp;          // find previous node   
        temp = temp->next;
    }
    if(temp!=a){// node[a] not present in list
        fprintf(stderr, "\n error: node not found!\n");
        exit(EXIT_FAILURE); // bad technique to exit()
    }
    return pre_a;   
}
幸运的是,代码正在工作:)。下面是这个代码在线测试的链接。我测试了各种输入

node[9] points to node[2]
node[6] points to node[5]     
代码板:请检查输出

node[9] points to node[2]
node[6] points to node[5]     
对不起,英语不好

node[9] points to node[2]
node[6] points to node[5]     
SwapanyTwoNodeData(int,int)
此函数将两个整数作为参数,并交换它们

node[9] points to node[2]
node[6] points to node[5]     
节点数据

node[9] points to node[2]
node[6] points to node[5]     
1->2->6->3->4->5 
swpanytwonodedata(2,4)

node[9] points to node[2]
node[6] points to node[5]     
1->3->6->2->4->5 
100%工作功能。享受

node[9] points to node[2]
node[6] points to node[5]     
void Swap_Any_Two_Locations_data(int x,int x1){

   if(head!=NULL){     
     int count=1,count1=1;     
     Node *temp,*temp1;
     temp=head;
     temp1=head;
     while(temp->next!=NULL && count!=x ){
         temp=temp->next;
         count++;
     }
     while(temp1->next!=NULL && count1!=x1){
         temp1=temp1->next;
         count1++;
     }
     if(count==x && count1==x1){
       int z=0;
       z=temp->info;
       temp->info=temp1->info;
       temp1->info=z;
       cout<<"Data Swapped"<<endl;
    }
  }
}
无效交换任意两个位置的数据(int x,int x1){
如果(head!=NULL){
int count=1,count1=1;
节点*temp,*temp1;
温度=水头;
temp1=头部;
while(临时->下一步!=NULL&&count!=x){
温度=温度->下一步;
计数++;
}
while(temp1->next!=NULL&&count1!=x1){
temp1=temp1->next;
count1++;
}
if(count==x&&count1==x1){
int z=0;
z=温度->信息;
temp->info=temp1->info;
temp1->info=z;

cout我希望剪切粘贴代码,但没有找到。如果还有人感兴趣,这就是答案。我对所有3个案例进行了暴力分析

node[9] points to node[2]
node[6] points to node[5]     
// swaps nodes at locations *sp and *tp
struct stack *s = *sp; // store locations to prevent overwritten bugs
struct stack *t = *tp;
if(&t->next == sp) { // order u (tp)-> t (sp)-> s -> ...
    t->next = s->next;
    s->next = t;
    *tp = s;
} else if(&s->next == tp) { // order u (sp)-> s (tp)-> t -> ...
    s->next = t->next;
    t->next = s;
    *sp = t;
} else { // disconnected u (sp)->s -> ..., v (tp)->t -> ...
    struct stack *next = s->next;
    s->next = t->next;
    t->next = next;
    *sp = t;
    *tp = s;
}             
// If you track the end of your list, it be the one pointing to NULL.                                           
if(s->next == NULL) {                                  
    end = &s->next;                                 
} else if(t->next == NULL) {                           
    end = &t->next;                                 
}

注意:此代码在sp==tp时有效,但假设您没有&s->next==tp&&t->next==sp(从循环开始)的病理情况虽然你只能用WASP数据,但是如果你想要的是节点,那么C++就不多了,只有C。你应该使用C++,并且用它代替现有的。我想简单地交换数据会更容易:<代码> DATAYTYPE TYMP=(*A)->数据;(*A)->数据=(*B)->数据;(*B)->data=temp;
@伙计们,我的代码有什么问题?:)@us2012-不使用它的原因是因为你被要求去理解它。这可能是一个学校项目,教授在OP自己完成之前不允许OP这么做。我理解反对这种教学方式的论点,因为我在这里读了一段时间这并没有改变我们中的一些人,包括我在内,都受到它的影响。没有规则规定你必须使用
STL
它只是sma
node[9] points to node[2]
node[6] points to node[5]