发布时间:2020-09-29 10:07 原文链接: 超详细的单链表学习教程(四)

70 }

71 // 从链表pH中删除节点,待删除的节点的特征是数据区等于data

72// 返回值:当找到并且成功删除了节点则返回0,当未找到节点时返回-1

73int delete_node(struct node*pH, int data)

74{

75// 找到这个待删除的节点,通过遍历链表来查找

76struct node *p = pH;

77    // 用来指向当前节点

78struct node *pPrev = NULL;

79// 用来指向当前节点的前一个节点

80while (NULL != p->pNext)        // 是不是最后一个节点

81{

82    pPrev = p;                  // 在p走向下一个节点前先将其保存

83    p = p->pNext;               // 走到下一个节点,也就是循环增量

84    // 判断这个节点是不是我们要找的那个节点

85    if (p->data == data)

86    {

87        // 找到了节点,处理这个节点

88        // 分为2种情况,一个是找到的是普通节点,另一个是找到的是尾节点

89        // 删除节点的困难点在于:通过链表的遍历依次访问各个节点,找到这个节点

90        // 后p指向了这个节点,但是要删除这个节点关键要操作前一个节点,但是这

91        // 时候已经没有指针指向前一个节点了,所以没法操作。解决方案就是增加

92        // 一个指针指向当前节点的前一个节点

93        if (NULL == p->pNext)

94        {

95            // 尾节点

96            pPrev->pNext = NULL;        // 原来尾节点的前一个节点变成新尾节点

97            free(p);                    // 释放原来的尾节点的内存

98        }

99        else

100        {

101            // 普通节点

102    pPrev->pNext = p->pNext;

103   // 要删除的节点的前一个节点和它的后一个节点相连,这样就把要删除的节点给摘出来了

104             free(p);

105        }

106        // 处理完成之后退出程序

107        return 0;

108    }

109}

110// 到这里还没找到,说明链表中没有我们想要的节点

111printf("没找到这个节点.n");

112return -1;

113}

114  // 将pH指向的链表逆序

115  void reverse_linkedlist(struct node *pH)

116  {

117struct node *p = pH->pNext;

118    // pH指向头节点,p指向第1个有效节点

119struct node *pBack;

120 // 保存当前节点的后一个节点地址

121// 当链表没有有效节点或者只有一个有效节点时,逆序不用做任何操作

122if ((NULL ==p) || (NULL == p->pNext))

123    return;

124// 当链表有2个及2个以上节点时才需要真正进行逆序操作

125while (NULL != p->pNext)        // 是不是最后一个节点

126{

127    // 原链表中第一个有效节点将是逆序后新链表的尾节点,尾节点的pNext指向NULL

128    pBack = p->pNext;           // 保存p节点后面一个节点地址

129    if (p == pH->pNext)

130    {

131        // 原链表第一个有效节点

132        p->pNext = NULL;

133    }

134    else

135    {

136        // 原链表的非第1个有效节点

137        p->pNext = pH->pNext;

138    }

139    pH->pNext = p;

140    //p = p->pNext;     // 这样已经不行了,因为p->pNext已经被改过了

141    p = pBack;          // 走到下一个节点

142}

143// 循环结束后,最后一个节点仍然缺失

144insert_head(pH, p);

145}

146int main(void)

147{

148    // 定义头指针

149    //struct node *pHeader = NULL;

150    // 这样直接insert_tail会段错误。

151    struct node *pHeader = create_node(0);

152    insert_head(pHeader, create_node(11));

153    insert_head(pHeader, create_node(12));

154    insert_head(pHeader, create_node(13));

155    // 访问链表头节点的有效数据

156    printf("beader node data: %d.n", pHeader->data);

157    bianli(pHeader);

158reverse_linkedlist(pHeader);

159printf("------------------逆序后-------------n");

160bianli(pHeader);

161    return 0;

162 }