C语言中字符的拆分链表

C语言中字符的拆分链表,c,split,linked-list,singly-linked-list,function-definition,C,Split,Linked List,Singly Linked List,Function Definition,我应该编写一个名为“disAssemblyList”的函数,该函数获取字符的链接列表(没有伪元素)。该函数应将带有大号字母的节点移动到“bigLetter”链接列表(无伪元素),将带有小号字母的节点移动到“smallLetter”链接列表,将NUM移动到“nums”链接列表,并将其他字符保留到原始列表中 我需要通过引用传递smallLetter、bigLetter和nums链接列表,并返回包含其他字符的列表。 typedef struct chNode { char data;

我应该编写一个名为“disAssemblyList”的函数,该函数获取字符的链接列表(没有伪元素)。该函数应将带有大号字母的节点移动到“bigLetter”链接列表(无伪元素),将带有小号字母的节点移动到“smallLetter”链接列表,将NUM移动到“nums”链接列表,并将其他字符保留到原始列表中

我需要通过引用传递smallLetter、bigLetter和nums链接列表,并返回包含其他字符的列表。

typedef struct chNode
{
    char data;
    struct chNode *next;
}chNode;


chNode * createCharList(char data)
{
    chNode *temp = (chNode*)malloc(sizeof(chNode));
    temp->data = data;
    temp->next = NULL;
    return temp;
}

chNode * addCharToLast(chNode *head, char data)
{
    chNode *p = head;
    chNode *temp = createCharList(data);
    if (head == NULL)
        return temp;
    while (p->next != NULL)
        p = p->next;
    p->next = temp;
    return head;
}

void printf_CharList(chNode *head)
{
    chNode *p = head;
    while (p != NULL)
    {
        printf("%d, ", p->data);
        p = p->next;
    }
    printf("\n\n");
}


chNode* insert_Charlist() // A function that imports numbers into a linked list , till -1
{
    char ch;
    chNode *Head = NULL;
    printf("Enter chars For Linked-List Till 'Enter':\n");
    //5scanf_s("%c", &ch);
    ch = getchar();
    while (ch != "\n")
    {

        Head = addCharToLast(Head, ch); //Makes last number to be First
        //scanf_s("%c", &ch);
        ch = getchar();
    }
    return Head;
}

void add_to_other_list(chNode** head, chNode* p)
{
    static chNode* tail = NULL;

    p->next = NULL;
    if (tail == NULL)
    {
        *head = p;
    }
    else
    {
        tail->next = p;
    }
    tail = p;
}


chNode* disAssemblyList(chNode* p, chNode **bigLetter, chNode **smallLetter, chNode **nums)
{
    chNode* t = NULL;

    if (p == NULL) return p;          // 0 elements
    if (p->next == NULL) return p;    // 1 element
    if (p->next->next == NULL)          // 2 elements
    {

        if ((p->next->data >= 65) && (p->next->data) <= 90)
        {
            // Move p->next to other list
            add_to_other_list(&(*bigLetter), p->next);
            p->next = NULL;
            return p;
        }
    }

    // Repeat as long as the list has minimum 3 elements
    while (p->next)
    {
        if ((p->next->data >= 65) && (p->next->data) <= 90)
        {
            // Move p-next
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*bigLetter), t);
        }

        if ((p->next->data >= 97) && (p->next->data) <= 122)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*smallLetter), t);
        }

        if ((p->next->data >= 48) && (p->next->data) <= 57)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*nums), t);

        }
        p = p->next;
    }

    return p;

}


void main()
{

    chNode *Orignial_list = NULL;
    chNode *bigLetter = NULL;
    chNode *smallLetter = NULL;
    chNode *nums = NULL;
    Orignial_list = insert_Charlist(); // Function that imports a list
    printf("You Entered This linked-list:\n");
    printf_CharList(Orignial_list); //Printing the linked list
    Orignial_list = disAssemblyList(Orignial_list,&bigLetter,&smallLetter,&nums);
    printf("The BigLetter Linked-List is:\n");
    printf_CharList(bigLetter);
    printf_CharList(smallLetter);
    printf_CharList(nums);
    printf_CharList(Orignial_list);
    getch();

}
我需要扫描原始列表。原始列表可以为空

例如:

原始链接列表:

3-> a-> 7-> M-> K-> u-> 5-> #-> &-> P-> %-> A
bigLetter

M-> K-> P-> A
a-> u
smallLetter

M-> K-> P-> A
a-> u
nums

3-> 7-> 5
其他字符(函数运行后的原始列表):

我写了这段代码,我似乎无法理解如何使它工作它不会扫描链接列表中的字符。

typedef struct chNode
{
    char data;
    struct chNode *next;
}chNode;


chNode * createCharList(char data)
{
    chNode *temp = (chNode*)malloc(sizeof(chNode));
    temp->data = data;
    temp->next = NULL;
    return temp;
}

chNode * addCharToLast(chNode *head, char data)
{
    chNode *p = head;
    chNode *temp = createCharList(data);
    if (head == NULL)
        return temp;
    while (p->next != NULL)
        p = p->next;
    p->next = temp;
    return head;
}

void printf_CharList(chNode *head)
{
    chNode *p = head;
    while (p != NULL)
    {
        printf("%d, ", p->data);
        p = p->next;
    }
    printf("\n\n");
}


chNode* insert_Charlist() // A function that imports numbers into a linked list , till -1
{
    char ch;
    chNode *Head = NULL;
    printf("Enter chars For Linked-List Till 'Enter':\n");
    //5scanf_s("%c", &ch);
    ch = getchar();
    while (ch != "\n")
    {

        Head = addCharToLast(Head, ch); //Makes last number to be First
        //scanf_s("%c", &ch);
        ch = getchar();
    }
    return Head;
}

void add_to_other_list(chNode** head, chNode* p)
{
    static chNode* tail = NULL;

    p->next = NULL;
    if (tail == NULL)
    {
        *head = p;
    }
    else
    {
        tail->next = p;
    }
    tail = p;
}


chNode* disAssemblyList(chNode* p, chNode **bigLetter, chNode **smallLetter, chNode **nums)
{
    chNode* t = NULL;

    if (p == NULL) return p;          // 0 elements
    if (p->next == NULL) return p;    // 1 element
    if (p->next->next == NULL)          // 2 elements
    {

        if ((p->next->data >= 65) && (p->next->data) <= 90)
        {
            // Move p->next to other list
            add_to_other_list(&(*bigLetter), p->next);
            p->next = NULL;
            return p;
        }
    }

    // Repeat as long as the list has minimum 3 elements
    while (p->next)
    {
        if ((p->next->data >= 65) && (p->next->data) <= 90)
        {
            // Move p-next
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*bigLetter), t);
        }

        if ((p->next->data >= 97) && (p->next->data) <= 122)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*smallLetter), t);
        }

        if ((p->next->data >= 48) && (p->next->data) <= 57)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*nums), t);

        }
        p = p->next;
    }

    return p;

}


void main()
{

    chNode *Orignial_list = NULL;
    chNode *bigLetter = NULL;
    chNode *smallLetter = NULL;
    chNode *nums = NULL;
    Orignial_list = insert_Charlist(); // Function that imports a list
    printf("You Entered This linked-list:\n");
    printf_CharList(Orignial_list); //Printing the linked list
    Orignial_list = disAssemblyList(Orignial_list,&bigLetter,&smallLetter,&nums);
    printf("The BigLetter Linked-List is:\n");
    printf_CharList(bigLetter);
    printf_CharList(smallLetter);
    printf_CharList(nums);
    printf_CharList(Orignial_list);
    getch();

}
typedef结构chNode
{
字符数据;
结构chNode*next;
}蛛网膜;
chNode*createCharList(字符数据)
{
chNode*temp=(chNode*)malloc(sizeof(chNode));
温度->数据=数据;
temp->next=NULL;
返回温度;
}
chNode*addCharToLast(chNode*head,char数据)
{
chNode*p=头部;
chNode*temp=createCharList(数据);
if(head==NULL)
返回温度;
while(p->next!=NULL)
p=p->next;
p->next=温度;
回流头;
}
无效打印字符表(chNode*head)
{
chNode*p=头部;
while(p!=NULL)
{
printf(“%d”,p->data);
p=p->next;
}
printf(“\n\n”);
}
chNode*insert_Charlist()//将数字导入链表的函数,直到-1
{
char ch;
chNode*Head=NULL;
printf(“输入链接列表的字符,直到‘输入’:\n”);
//5scanf_s(“%c”和“ch”);
ch=getchar();
而(ch!=“\n”)
{
Head=addCharToLast(Head,ch);//将最后一个数字设为第一个
//scanf_s(“%c”和“ch”);
ch=getchar();
}
回流头;
}
无效添加到其他列表(chNode**头,chNode*p)
{
静态chNode*tail=NULL;
p->next=NULL;
if(tail==NULL)
{
*水头=p;
}
其他的
{
尾部->下一步=p;
}
尾=p;
}
chNode*disAssemblyList(chNode*p,chNode**bigLetter,chNode**smallLetter,chNode**nums)
{
chNode*t=NULL;
if(p==NULL)返回p;//0个元素
if(p->next==NULL)返回p;//1元素
如果(p->next->next==NULL)//2个元素
{
如果其他列表旁边的((p->next->data>=65)和&(p->next->data)
将_添加到_其他_列表(&(*bigLetter),p->next);
p->next=NULL;
返回p;
}
}
//只要列表中至少有3个元素,就重复此操作
while(p->next)
{
如果((p->next->data>=65)和&(p->next->data)next;
p->next=p->next->next;
添加到其他列表(&(*大字母),t);
}
如果((p->next->data>=97)和&(p->next->data)next;
p->next=p->next->next;
将字母添加到其他字母列表(&(*小写字母),t);
}
如果((p->next->data>=48)和&(p->next->data)next;
p->next=p->next->next;
添加到其他列表(&(*nums),t);
}
p=p->next;
}
返回p;
}
void main()
{
chNode*Orignial_list=NULL;
chNode*bigLetter=NULL;
chNode*smallLetter=NULL;
chNode*nums=NULL;
Orignial_list=insert_Charlist();//导入列表的函数
printf(“您输入了此链接列表:\n”);
printf_CharList(Orignial_list);//打印链接列表
Original_列表=分解列表(Original_列表和bigLetter、smallLetter和nums);
printf(“BigLetter链接列表是:\n”);
打印字符表(bigLetter);
打印字符表(小写字母);
打印字符表(nums);
打印字符表(原始字符表);
getch();
}

我没有看完您的所有代码,因为据我所知,问题是关于一个函数实现,它将原始列表拆分为其他一些列表

尽管我确信您的代码中存在缺陷,例如函数
print\u CharList
输出字符的内部代码,而不是存储在列表中的字符本身

void printf_CharList(chNode *head)
{
    chNode *p = head;
    while (p != NULL)
    {
        printf("%d, ", p->data);
        p = p->next;
    }
    printf("\n\n");
}
或者,使用静态变量的函数
将\u添加到\u其他\u列表
没有意义

或者在函数的开头出现这种情况
disAssemblyList

if (p->next == NULL) return p;    // 1 elementNevertheless the function 
也没有道理

尽管如此,拆分列表的函数可以如下面的演示程序所示

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct chNode
{
    char data;
    struct chNode *next;
} chNode;

void clear( chNode **head )
{
    while ( *head != NULL )
    {
        chNode *tmp = *head;
        *head = ( *head )->next;
        free( tmp );
    }
}

size_t assign( chNode **head, const char *s )
{
    if ( *head ) clear( head );
    
    size_t n = 0;
    
    while ( *s && ( *head = malloc( sizeof( chNode ) ) ) != NULL )
    {
        ( *head )->data = *s++;
        ( *head )->next = NULL;
        head = &( *head )->next;
        ++n;
    }
    
    return n;
}

FILE * display( const chNode *head, FILE *fp )
{
    for ( ; head != NULL; head = head->next )
    {
        fprintf( fp, "%c -> ", head->data );
    }
    
    fputs( "null", fp );
    
    return fp;
}

chNode * disAssemblyList( chNode *p, 
                          chNode **bigLetter, 
                          chNode **smallLetter, 
                          chNode **nums )
{
    while ( *bigLetter ) bigLetter = &( *bigLetter )->next;
    while ( *smallLetter ) smallLetter = &( *smallLetter )->next;
    while ( *nums ) nums = &( *nums )->next;

    chNode **head = &p;
    
    while ( *head != NULL )
    {
        if ( isdigit( ( unsigned char )( *head )->data ) )
        {
            *nums = *head;
            *head = ( *head )->next;
            ( *nums )->next = NULL;
            nums = &( *nums )->next;
        }
        else if ( isupper( ( unsigned char )( *head )->data ) )
        {
            *bigLetter = *head;
            *head = ( *head )->next;
            ( *bigLetter )->next = NULL;
            bigLetter = &( *bigLetter )->next;
        }
        else if ( islower( ( unsigned char )( *head )->data ) )
        {
            *smallLetter = *head;
            *head = ( *head )->next;
            ( *smallLetter )->next = NULL;
            smallLetter = &( *smallLetter )->next;
        }
        else
        {
            head = &( *head )->next;
        }
    }
    
    return p;
}   

int main(void) 
{
    chNode *head = NULL;
    
    assign( &head, "3a7MKu5#&P%A" );
    
    fputc( '\n', display( head, stdout ) );
    
    putchar( '\n' );
    
    chNode *bigLetter = NULL;
    chNode *smallLetter = NULL;
    chNode *nums = NULL;
    
    head = disAssemblyList( head, &bigLetter, &smallLetter, &nums );
    
    fputc( '\n', display( head, stdout ) );
    fputc( '\n', display( bigLetter, stdout ) );
    fputc( '\n', display( smallLetter, stdout ) );
    fputc( '\n', display( nums, stdout ) );
    
    clear( &head );
    clear( &bigLetter );
    clear( &smallLetter );
    clear( &nums );

    return 0;
}     
如果不允许使用标题
中的标准C函数,则函数
disAssemblyList
中的while循环可能如下所示

    while ( *head != NULL )
    {
        char c = ( *head )->data;

        if ( '0' <= c && c <= '9' )
        {
            *nums = *head;
            *head = ( *head )->next;
            ( *nums )->next = NULL;
            nums = &( *nums )->next;
        }
        else if ( 'A' <= c && c <= 'Z' )
        {
            *bigLetter = *head;
            *head = ( *head )->next;
            ( *bigLetter )->next = NULL;
            bigLetter = &( *bigLetter )->next;
        }
        else if ( 'a' <= c && c <= 'z' )
        {
            *smallLetter = *head;
            *head = ( *head )->next;
            ( *smallLetter )->next = NULL;
            smallLetter = &( *smallLetter )->next;
        }
        else
        {
            head = &( *head )->next;
        }
    }
while(*head!=NULL)
{
字符c=(*head)->数据;
如果('0'下一步=NULL;
nums=&(*nums)->下一步;
}
else if('A'next=NULL;
bigLetter=&(*bigLetter)->下一步;
}
else if('a'next=NULL;
smallLetter=&(*smallLetter)->下一步;
}
其他的
{
头部=&(*头部)->下一步;
}
}

您的代码中有一些小问题和两个大问题

首先是小问题:

  • 代码不包含所需的内容,包括:

      #include <stdio.h>
      #include <stdlib.h>
    
  • 您无法释放分配的内存。这不是一个大问题,因为它将在程序结束时返回到环境中,但最佳实践建议始终
    释放
    已分配的内存

现在来谈谈严重的问题。两个基本函数
add_to_other_list
disAssemblyList
都被完全破坏了。现在是时候学习如何使用调试器逐步调试代码,看看会发生什么。更糟糕的是,它们的一般逻辑被破坏了,我不得不重新编写它们:

void add_to_other_list(chNode** head, chNode* p)
{
    static chNode* tail;

    p->next = NULL;
    if (*head == NULL)
    {
        *head = p;
    }
    else
    {
        for (tail=*head; tail->next != NULL; tail = tail->next);  //skip to end of list
        tail->next = p;
    }
}

chNode* disAssemblyList(chNode* head, chNode **bigLetter, chNode **smallLetter, chNode **nums)
{
    chNode dummy = {0, head};  // build a dummy node to start one before current head
    chNode *p = &dummy;
    chNode* t;

    // Repeat as long as the list has minimum 1 element to process
    while (p->next)
    {
        if ((p->next->data >= 65) && (p->next->data) <= 90)
        {
            // Move p-next
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*bigLetter), t);
        }

        else if ((p->next->data >= 97) && (p->next->data) <= 122)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*smallLetter), t);
        }

        else if ((p->next->data >= 48) && (p->next->data) <= 57)
        {
            t = p->next;
            p->next = p->next->next;
            add_to_other_list(&(*nums), t);

        }
        else p = p->next;   // only advance p if p->next has not been moved
    }

    return dummy.next;

}
void添加到其他列表(chNode**head,chNode*p)
{
静态中缝*尾;
p->next=NULL;
如果(*head==NULL)