注册 登录
编程论坛 C语言论坛

链表问题求助,唯一化函数出了些问题

深梦沉睡 发布于 2017-08-17 23:22, 1283 次点击
唯一化函数LDulipcate()停在第一次循环,打印出“1”后就不动了
如图
只有本站会员才能查看附件,请 登录
7 回复
#2
深梦沉睡2017-08-17 23:22



程序代码:
#include<stdio.h>
#include<stdlib.h>
//类型声明
//节点数据
typedef int ElemType;
//节点
typedef struct Node{
    ElemType data;
    struct Node *next;
}Node;
//链表
typedef struct List{
    int size;
    Node header;
    Node tailer;
}List;


int main(void){
    List l,*lp1,;
    lp1=_ListInit();
    lp1=ListInsertData(lp1,20);
    lp1=ListInsertData(lp1,20);
    lp1=ListInsertData(lp1,20);
    lp1=ListInsertData(lp1,40);
    lp1=ListInsertData(lp1,40);
    printf("\n---------\nlp1:\n");
    ListPrint(lp1);
    lp1=ListDeduplicate(lp1);
    printf("\n---------\nlp1:\n");
    ListPrint(lp1);
    return 0;
}
//链表建立
List *_ListInit(void){
    List *L;
    L=(List *)malloc(sizeof(List));
    L->header.next=&(L->tailer);
    L->tailer.next=NULL;
    L->size=0;
    L->header.data=0;
    L->tailer.data=0;
    printf("List create successfully!\n");
    return L;
}
//链表插入,接受数据
//作为头指针的下一个节点插入
List *ListInsertData(List *L,ElemType Data){
    if (!L)printf("Error!");
    Node N;
    N.next=L->header.next;//将原首元素接到临时指针上
    L->header.next=(Node *)malloc(sizeof(Node));//头元素的指针域生成新节点
    L->header.next->data=Data;//赋值
    L->header.next->next=N.next;//原来的节点接到新增节点后
    L->size++;
    return L;
}
//链表唯一化
List *ListDeduplicate(List *L){
    Node *temp,*N=L->header.next; //从首元素开始
    ElemType Data; int i=1;
    while(NULL!=N->next){//到达尾节点
        N=L->header.next;
        Data=N->data;
        while(NULL!=N->next){
            N=N->next;
            if(N->data==Data){
                printf("%d\n",i);i++;
                temp=N->next->next;
                N->next=temp;
                free(temp);
                L->size--;
            }
        }
    }
    return L;
}
//遍历打印
void ListPrint(List *L){
    if(!L)printf("Error!");
    if(L->size==0)printf("Empty List!\n");
    Node *N=L->header.next;//临时指针指向首元素
    int i=1;
    printf("List length:%d\n",L->size);
    while(NULL!=N->next){
        printf("number:%d\tdata:%d\n",i,N->data);
        N=N->next;
        i++;
    }
    printf("---------\n");
}
#3
深梦沉睡2017-08-19 00:12
改了改,还是不行
程序代码:

    typedef int ElemType;
//节点
typedef struct Node{
    ElemType data;
    struct Node *next;
}Node;
//链表
//链表长度,头节点,尾节点
typedef struct List{
    int size;
    Node *header;
    Node *tailer;
}List;


    List *ListDeduplicate(List *L){
    Node *temp,*N=L->header->next,*M=L->header->next; //从首元素开始
    ElemType Data;
    if(NULL==N->next){printf("Elmty List!\n");return L;}
    while(NULL!=M->next->next){ //首元素数据参与操作,不需要移动到尾元素
        Data=M->data;
        N=M;
        while(NULL!=N->next->next){//末元素数据参与操作
            N=N->next;
            if(N->data==Data){
                temp=N->next;
                N->next=temp->next;
                free(temp);
                L->size--;
            }
        }
        M=M->next;
    }
    return L;
}
#4
marlow2017-08-19 19:12
ListDeduplicate(List *L)作用是去掉链表中数据重复的节点吗?
粗略看了一下,表示不大看得懂你的算法。
一个while()循环应该就可以搞的东西,为什么要用两个循环呢?
另外, L->header.next=&(L->tailer)起什么作用?好像后面的代码中再也没出现过tailer了
#5
深梦沉睡2017-08-19 23:26
是的,ListDulipcate()是为了删除重复节点。
tailer是尾节点,和头节点差不多,L->header.next=&(L->tailer)是把尾节点作为头节点的后继,插入元素时插在两者间。

我想用外循环依次访问数据,内循环在后继中寻找相应的重复数据并删除节点。
请问只用一个while()循环的思路是怎样的?

程序代码:

    List *ListDeduplicate(List *L){
    Node *temp,*N=L->header->next,*M=L->header->next; //从首元素开始
    ElemType Data;
    if(NULL==N->next){printf("Elmty List!\n");return L;}//判空
    while(NULL!=M->next->next){
        Data=M->data;//确定需要处理的数据
        N=M;//从M的下一个节点开始,找到重复元素,直到最后一个有数据的元素
        while(NULL!=N->next->next){
            N=N->next;
            if(N->data==Data){
                temp=N->next;//删除重复节点
                N->next=temp->next;
                free(temp);
                L->size--;
            }
        }
        M=M->next;
    }
    return L;
}
#6
marlow2017-08-20 06:52
恩,确实需要两个循环,一个依次指向链表的节点,另一个删除剩余节点中相同的,那个什么tailer明显是多余

[此贴子已经被作者于2017-8-20 07:04编辑过]

#7
marlow2017-08-20 07:39
你在if判断的最后加一条continue,并把N=N->next移到这个if的后面试试
#8
marlow2017-08-21 12:25
回复 7楼 marlow
这样改就好了!
程序代码:
List *ListDeduplicate(List *L){
    Node *temp, *prep, *N, *M = L->header.next; //从首元素开始
    ElemType Data;
    if(NULL==M->next){printf("Elmty List!\n");return L;}//判空
    while(NULL!=M->next){
        Data=M->data;//确定需要处理的数据
        prep = M;
        N = M->next;
        while(NULL!=N->next){
            if(N->data==Data){
                prep->next = N->next;
                free(N);
                L->size--;
                N = prep->next;
            }else{
                prep = N;
                N = N->next;
            }
        }
        M = M->next;
    }
    return L;
}


[此贴子已经被作者于2017-8-21 12:50编辑过]

1