标题:@renkejun1942 求一个链表逆序的泛型函数~
只看楼主
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
结帖率:99.25%
已结贴  问题点数:100 回复次数:9 
@renkejun1942 求一个链表逆序的泛型函数~
@renkejun1942

最近做到广搜时打算在队尾用一个指针链接到队头来标记其遍历状态~以便于回溯搜索~不过这样打印出来的结果会是逆序的~现在有必要进行把的到数据进行逆序输出~当然也有其它处理方法例如交换搜索起点和终点~但这样究竟还是有很大的局限性~当然我自己也可以尝试敲敲~不过最近编程和学习还有别的任务就没啥时间去弄了~~如果有时间麻烦能不能弄个链表逆序的泛型函数~拜托了~~~
搜索更多相关主题的帖子: 起点 局限性 
2017-04-24 21:07
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:100 
常规的逆序就可以了哦,逆序只涉及Link字段的值的修改。
而且常规的逆序几乎就是万能的,对任何框架的结构都适用,只要链接字段的名字相同。
而链接字段的名字现在几乎都有不成文的约定,要么是Next,要么是Link,而Link更多。

结构框架有办法实现,我想到的就是值域是一个不完整声明的结构,(利用相同结构可以直接赋值达成),而完整声明由客户程序提供。

程序代码:
List *
ReverseList( List *RootP )
{
    Node *current;
    Node *next;

    for( current = NULL; NULL != RootP; RootP = next )
    {
        next = RootP->link;
        RootP->Link = current;
        current = RootP;
    }

    return current;
}






[此贴子已经被作者于2017-4-24 22:01编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-24 21:25
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 2楼 renkejun1942
感觉可以先自己做一个模板代码~然后用时就在模板代码上修改数据类型然后copy过去就可以了~还是谢过啦~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-24 22:04
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 3楼 九转星河
对的,这就是变相了。

我看了下其他语言的泛型链表,好像差不多也是这样。

差不多就是这样了,我尝试完成,目前还在构思头文件,看看需要哪些操作。
但是这样做,还是只能拥有一个类型的链表,我还需要再想想。

仔细考虑之后,我发现了,我在错误中前行,我为什么会需要在结构中固定一个类型,void指针真好用。

或者,我又用宏搞一个,想想都好玩。


[此贴子已经被作者于2017-4-24 22:28编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-24 22:10
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 4楼 renkejun1942
看了看~感觉链表操作有几个函数可以通用~
1~创建节点
2~插入节点
3~删除节点
4~销毁链表
5~链表转置~



[此贴子已经被作者于2017-4-24 23:08编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-24 23:07
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 5楼 九转星河
嗯嗯,我有点思路了,Insert函数正在处理值的问题,应该很快可以搞定。
打印函数已经搞定了

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-24 23:15
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
目前只完成了打印和插入。
思路借鉴了库函数qsort,由用户程序提供比较和具体的打印函数,List函数执行具体的操作,插入,删除,打印,遍历等等等。
其他几个函数,几乎已经没有难度了,随便写写了。


程序代码:
//测试:
#include <stdio.h>
#include "GenericityList.h"
int
COM( void *a, void *b );
void
PRINT( void * );

struct a
{
    int a;
    double b;
    char c;
};

int
main( void )
{
    List Root;
    struct a b;
    int ix;

    Root = NULL;

    for( ix = 0; ix < 20; ++ix )
    {
        b.a = 'a' + ix;
        b.b = 'a' + ix;
        b.c = 'a' - ix;
        Insert( &Root, &b, sizeof( struct a ), COM );
    }

    Print( Root, PRINT );
    return 0;
}

int
COM( void *a, void *b )
{
    return 1;
}

void
PRINT( void *a )
{
    printf("%d %c %lf",( int )( ( ( struct a * )a )->a ),( char )( ( ( struct a * )a )->b ),( double )( ( ( struct a * )a )->c ) );
}

程序代码:
//接口:
#ifndef _GENERICITY_LIST_
#define _GENERICITY_LIST_


struct List{
    void *Element;
    struct List *Link;
};

typedef struct List *List;

void 
Insert( List *RootPP, void *Value, int size , int (*compare)( void *, void * ) );

void
Print( List RootP, void (*)( void * ) );


#endif

程序代码:
//实现:
#include "GenericityList.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>

void
Insert( List *RootPP, void *Value, int size , int (*compare)( void *, void * ) )
{
    List Next;
    List NewCell;

    while( NULL != ( Next = *RootPP ) && 0 < compare( Next->Element, Value ) )
        RootPP = &Next->Link;

    NewCell = ( List )malloc( sizeof( struct List ) );
    assert( NULL != NewCell );
    NewCell->Element = malloc( size );
    assert( NULL != NewCell->Element );
    memmove( NewCell->Element, Value, size );
    NewCell->Link = Next;
    *RootPP = NewCell;
}

void
Print( List RootP, void (*print)( void * ) )
{
    while( NULL != RootP )
    {
        print( RootP->Element );
        RootP = RootP->Link;
        printf( "\n" );
    }
}




[此贴子已经被作者于2017-4-24 23:43编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-24 23:28
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 6楼 renkejun1942
感觉插入应该只是new出节点并用memset初始化清零~然后在插入函数外面赋值~

写了个创建链表和销毁链表的泛型代码~
Link.h
程序代码:
#include<stdlib.h>
#include<string.h>
#include<assert.h>

//PTYPE 链表指针类型  NAME 函数名称 LEN 链表容量大小 NEXT链表指针名称 
#define MAKE(PTYPE,NAME,LEN,NEXT) \
\
void Creat_Node_##NAME(PTYPE* p) \
{   \
   *p=(PTYPE)malloc(LEN); \
   assert(*p!=NULL);  \
   memset(*p,0,LEN);   \
} \
\
void Del_One_##NAME(PTYPE* p) \
{  \
    if (*p==NULL)  \
        return ;  \
  \
    free(*p);  \
    *p=NULL;  \
}  \
void Del_Link_##NAME(PTYPE* p) \
{ \
    PTYPE t=*p;  \
    while (t=t->##NEXT)  \
    {  \
        Del_One_##NAME(p);  \
         *p=t;  \
    }  \
\
    *p=NULL;  \
} 




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

typedef struct Node
{
    int n;
    struct Node* next;
}Node,*PNode;


MAKE(PNode,S,sizeof(Node),next)

PNode Creat_S(PNode p);
void Print(PNode p);

int main()
{
    PNode head=NULL;
    Creat_Node_S(&head);

    head=Creat_S(head);

    Print(head);

    Del_Link_S(&head);

    return 0;
}

PNode Creat_S(PNode head)
{
    int n=0;
    PNode p=NULL;
    PNode t=NULL;

    if (head==NULL)
        Creat_Node_S(&head);

    p=head;

    while (p->next)
        p=p->next;

    while (scanf("%d",&n)!=EOF)
    {
        Creat_Node_S(&t);
        t->n=n;
        p=p->next=t;
    }

    return head;
}

void Print(PNode p)
{
    if (p==NULL||p->next==NULL)
    {
        puts("这是一张空表!");
        return ;
    }

    while (p=p->next)
        printf("%-3d",p->n);

    puts("");
}

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-04-24 23:32
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 8楼 九转星河
七楼更新了,目前已经完成的两个函数。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-24 23:34
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
完成了,发在这个帖子里。

https://bbs.bccn.net/thread-476405-1-1.html

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-04-25 00:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-476399-1-1.html




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

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