从c中的节点列表中删除元素

时间:2018-01-10 14:28:50

标签: c list nodes singly-linked-list

这是我的结构:

struct Node {
    String value; // dynamically allocated string, release memory!
    struct Node* next; // self-reference
};
typedef struct Node Node;

现在我需要一个可以删除列表元素的函数。

Node* remove_list(Node* list, int index) {}

我知道它应该如何运作。但我不知道如何把它放在代码中......

这是我的想法:

        Node *tmp = list->next;
        list->next = list->next->next;
        free_list (tmp);
        return list;

此代码删除列表的第二个元素,但仅当列表不超过2个元素时... 如果有超过2个元素,则终端中会出现以下错误:

Segmentation fault: 11

该函数应删除索引i的元素..

我不知道如何制作它。

2 个答案:

答案 0 :(得分:0)

apply plugin: 'com.android.application'

android {
compileSdkVersion 26
defaultConfig {
    applicationId "com.example.demouser.scarnesdice"
    minSdkVersion 22
    targetSdkVersion 26
    multiDexEnabled true
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner 
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 
'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-
core:3.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
}

repositories {
maven {
    url 'https://maven.google.com'
}
}

在您没有进行list->next = list->next->next; 检查的情况下 - 您已经dereferrenced NULL导致您未定义的行为(在您的情况下是分段错误)。 (如果NULL)。

另外为什么在这里使用递归?只需list->next = NULL循环即可完成工作。

例如,

for

答案 1 :(得分:0)

可以在演示程序中显示该功能。 注意也应该删除分配的字符串。

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

typedef char * String;

struct Node 
{
    String value; // dynamically allocated string, release memory!
    struct Node *next; // self-reference
};

typedef struct Node Node;

Node * remove_list( Node *list, size_t index )
{
    Node **current = &list;

    while ( *current && index ) 
    {
        current = &( *current )->next;
        --index;
    }

    if ( *current )
    {
        Node *tmp = *current;
        *current = ( *current )->next;

        free( tmp->value );
        free( tmp );
    }

    return list;
}

Node * push( Node *list, const char *value )
{
    Node *tmp = malloc( sizeof( Node ) );

    tmp->value = malloc( strlen( value ) + 1 );
    strcpy( tmp->value, value );

    tmp->next = list;

    return tmp;
}

void display( Node *list )
{
    for ( ; list; list = list->next )
    {
        printf( "%s ", list->value );
    }
}

int main(void) 
{
    Node *list = NULL;
    char value[] = "A";

    for ( size_t i = 0; i < 'Z' - 'A' + 1; i++ )
    {
        list = push( list, value );
        ++value[0];
    }


    display( list );
    putchar( '\n' );

    list = remove_list( list, 25 );
    display( list );
    putchar( '\n' );

    list = remove_list( list, 0 );
    display( list );
    putchar( '\n' );

    list = remove_list( list, 10 );
    display( list );
    putchar( '\n' );

    return 0;
}

程序输出

Z Y X W V U T S R Q P O N M L K J I H G F E D C B A 
Z Y X W V U T S R Q P O N M L K J I H G F E D C B 
Y X W V U T S R Q P O N M L K J I H G F E D C B 
Y X W V U T S R Q P N M L K J I H G F E D C B 

或者这是另一个示范程序

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

typedef char * String;

struct Node 
{
    String value; // dynamically allocated string, release memory!
    struct Node *next; // self-reference
};

typedef struct Node Node;

Node * remove_list( Node *list, size_t index )
{
    Node **current = &list;

    while ( *current && index ) 
    {
        current = &( *current )->next;
        --index;
    }

    if ( *current )
    {
        Node *tmp = *current;
        *current = ( *current )->next;

        free( tmp->value );
        free( tmp );
    }

    return list;
}

Node * push( Node *list, const char *value )
{
    Node *tmp = malloc( sizeof( Node ) );

    tmp->value = malloc( strlen( value ) + 1 );
    strcpy( tmp->value, value );

    tmp->next = list;

    return tmp;
}

void display( Node *list )
{
    for ( ; list; list = list->next )
    {
        printf( "%s ", list->value );
    }
}

int main(void) 
{
    Node *list = NULL;
    char value[] = "A";

    for ( size_t i = 0; i < 'Z' - 'A' + 1; i++ )
    {
        list = push( list, value );
        ++value[0];
    }

    while ( list )
    {
        display( list );
        putchar( '\n' );
        list = remove_list( list, 0 );
    }

    return 0;
}

此时程序输出可能看起来像

Z Y X W V U T S R Q P O N M L K J I H G F E D C B A 
Y X W V U T S R Q P O N M L K J I H G F E D C B A 
X W V U T S R Q P O N M L K J I H G F E D C B A 
W V U T S R Q P O N M L K J I H G F E D C B A 
V U T S R Q P O N M L K J I H G F E D C B A 
U T S R Q P O N M L K J I H G F E D C B A 
T S R Q P O N M L K J I H G F E D C B A 
S R Q P O N M L K J I H G F E D C B A 
R Q P O N M L K J I H G F E D C B A 
Q P O N M L K J I H G F E D C B A 
P O N M L K J I H G F E D C B A 
O N M L K J I H G F E D C B A 
N M L K J I H G F E D C B A 
M L K J I H G F E D C B A 
L K J I H G F E D C B A 
K J I H G F E D C B A 
J I H G F E D C B A 
I H G F E D C B A 
H G F E D C B A 
G F E D C B A 
F E D C B A 
E D C B A 
D C B A 
C B A 
B A 
A 

另一方面功能界面不好。当函数报告它是删除给定节点还是没有删除时,它会更好。

所以我自己会声明像

这样的功能
int remove_list( Node **list, size_t index );