| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1905 人关注过本帖, 1 人收藏
标题:分享:简单的链表操作
取消只看楼主 加入收藏
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
结帖率:95.65%
收藏(1)
 问题点数:0 回复次数:10 
分享:简单的链表操作
链表的所有操作,无论插入,还是删除节点,还是逆序,都是对next值的修改!!!!!!!!!
再此,根指针是一个特例,原因在于,函数无法访问根指针,因此这里需要二级指针。
当然,解决函数无法访问根指针有多个办法,第一,传递一个完整的节点。第二,全局变量。第三,二级指针。
这样一看,二级指针可谓最优化选择。



至于双链表,我还有一个最后的查找没有完成。悲剧。因为双链表,可以从多个方向进行遍历,所以一直没有完成。

程序代码:
//调用示例:
#include <stdio.h>
#include "List.h"

int
main( void )
{
    Node *Root;
    Node *P;
    int value;

    Root = NULL;

    while( 1 == scanf( "%d", &value ) )//插入测试,升序。如要按照输入顺序插入,那么需要删除InsertNode  while循环中的值判断
        InsertList( &Root, value );
    PrintList( Root, ' ' );//打印测试。该函数接受一个节点指针和一个字符,用来作为打印的分割符。
    printf( "\n" );

    getchar();

    while( 1 == scanf( "%d", &value ) )
        DeleteNode( &Root, value );//删除节点,接受一个节点指针和一个值,注意,你需要传递该指针本身的地址。
    PrintList( Root, ' ' );
    printf( "\n" );

    Root = ReverseList( Root );//逆序。返回新链表的指针。这里可以也可以用二级指针来做到没有返回值,但是不够灵活。
    PrintList( Root, ' ' );
    printf( "\n" );

    getchar();
    while( 1 == scanf( "%d", &value ) )
    {
        P = FindNode( Root, value );
        printf("%d",P->Value);
    }

    DeleteList( &Root );//删除链表。

    return 0;
}


程序代码:
#ifndef List_H
#define List_H
typedef struct NODE {
    int Value;
    struct NODE *Next;
}Node; 

void 
PrintList( Node *RootP,char Spacech );
int 
InsertList( Node **RootP, int value );
void 
DeleteList( Node **RootP );
void 
DeleteNode( Node **RootP, int value );
Node *
FindNode( Node *Root, int value );
Node *
ReverseList( Node *first );
#endif



程序代码:
#include <stdio.h>
#include <stdlib.h>
#include "List.h"

int 
InsertList( Node **RootP, int value )
{
    Node *NewCell;
    Node *Current;

    while( NULL != ( Current = *RootP ) && value > Current->Value )
        RootP = &Current->Next;//Current往前遍历,用RootP来保存之前的Next值,这样,当Current找到插入点的时候,RootP就可以告诉我们,那个Next需要修改
                               //至于链表为空,还是插入点为头部,尾部,这些无需考虑,因为newcell->next一定是指向current,
    
    NewCell = (Node *)malloc( sizeof(Node) );
    if( NULL == NewCell )
        return 0;
    NewCell->Value = value;
    NewCell->Next = Current;
    *RootP = NewCell;

    return 1;

}

void 
DeleteNode( Node **RootP , int value )
{
    Node *Current;

    while( NULL != ( Current = *RootP ) && value != Current->Value )
        RootP = &Current->Next;//如上

    if( NULL == Current )
        return;
    *RootP = Current->Next;
    free( Current );
}

void 
PrintList( Node *RootP, char Spacech )
{
    Node *Current;

    while( NULL != ( Current = RootP ) )
    {
        printf("%d%c",Current->Value,Spacech);
        RootP = Current->Next;
    }
}


void 
DeleteList( Node **RootP )
{
    Node *Current;
    Node *Temp;

    Current = *RootP;
    *RootP = NULL;//根指针设置为NULL

    while( NULL != Current )
    {
        Temp = Current->Next;//Temp保存下一节点
        free( Current );//释放当前节点
        Current = Temp;//更新Current的值
    }
}


Node *
FindNode( Node *Root, int value )
{
    Node *Next;

    while( NULL != ( Next = Root ) && Next->Value != value )
        Root = Next->Next;

    return Next;
}

Node *
ReverseList( Node *first )
{
    Node *current;
    Node *next;

    for( current = NULL; NULL != first; first = next )
    {//first往前遍历,next保存下一节点。这样,first的值就是需要修改的值。
        next = first->Next;
        first->Next = current;
        current = first;
    }

    return current;
}



[此贴子已经被作者于2017-3-21 20:38编辑过]

搜索更多相关主题的帖子: color 
2017-03-21 19:51
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 2楼 yangfrancis
我在帖子的最开始写了啊。一切操作都是对Next的修改,函数中的东西无非是遍历,查找。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:09
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 3楼 wp231957
我在帖子的最开始写了啊。一切操作都是对Next的修改,函数中的东西无非是遍历,查找。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:09
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 6楼 wp231957
好吧,我加上一些必须的注释。
还是帖子最开始的话了,一切操作都是对Next的修改。

Next似乎是一个约定,指向链表下一节点的指针应该命名为Next。(反正我在大部分的书上看到的命名都是Next)。
双链表的指针,一般命名为prev和next,我曾经命名为left和right,被吐槽了半天。

[此贴子已经被作者于2017-3-21 20:41编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:14
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 8楼 wp231957
在逆序函数中,最后的时候current指向的是最后一个节点。
但是在遍历的过程中,所有节点的next都被修改,所以,它也就是第一节点。
是的,他是第一节点,不是根指针。这里用的是一级指针,在函数中是无法访问根指针的。

[此贴子已经被作者于2017-3-21 20:44编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:42
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 10楼 wp231957
好奇怪,你最后那串奇怪的数字怎么多出来的?
你在两次打印的时候,用了两个不同的打印函数,应该是第二个函数的问题。

[此贴子已经被作者于2017-3-21 20:48编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:45
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 12楼 wp231957
他是一个节点的。
如果是一级指针,那么他就是节点。
如果是二级指针,那么他是根指针。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:55
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
有一个节点不见了。然后多出了一个奇怪的数字。
终于知道是在linkcre的问题,具体还在看这个函数。这个函数好复杂啊,楞是没搞清楚彼此的关系。

那个神秘数字应该是在malloc的锅,因为他分配了空间,但是你没有对他进行初始化。

[此贴子已经被作者于2017-3-21 21:08编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 20:57
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 16楼 wp231957
我不太明白,你说的Head是什么,是头节点,还是头指针。

如果是头节点的话,那么他返回的就是头节点。具体的,我在9楼还是几楼给了你回复。
如果是头指针的话,一级指针,函数无法访问头指针。

[此贴子已经被作者于2017-3-21 21:07编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 21:06
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:0 
回复 18楼 wp231957
就算你是用它当第一个节点,这个节点是有名字的,俗称哑节点,意思是没他什么事。
但是即使是这样,你也应该对他初始化啊,最起码,把它的值设置为了NULL。
而且,既然他是一个完整的节点,那么还需要head做什么呢?

我看了好久,没看懂你那个函数各个指针之间的关系。

[此贴子已经被作者于2017-3-21 21:15编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-03-21 21:12
快速回复:分享:简单的链表操作
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.096581 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved