数据结构C语言——单向链表及其实现

数据结构C语言——单向链表

悄悄告诉你,之前因为Linux环境没配好,代码可能有忆点bug,嘻嘻,不过框架没得问题。后边的代码都测试过了,有些地方没做输入参数的校验和昉内存泄露的处理,不过问题不大。。。

文章目录

  • 数据结构C语言——单向链表
    • 1 有头单链表
    • 2 无头单链表
    • 3 单向循环链表

1 有头单链表

头节点不存储有效数据,便于对链表操作。(Linux环境没配好,代码没测可能有亿点bug)

makefile

all:main

main:main.o list.o
	$(CC) $^ -o $@
	
clean:
	rm *.o main -rf

list.h

#ifndef LIST_H__
#define LIST_H__

#define DATASIZE	1024
typedef int datatype; 

struct node_st{
    datatype data;
    struct node_st *next;
}linknode;

list *list_create();

int list_insert_at(list *, int i, datatype *);
int list_order_insert(list *, datatype *);

int list_delete_at(list *, int i, datatype *);
int list_delete(list *, datatype *);

int list_isempty(list *);
void list_display(list *);
void list_destroy(list *);
#endif

list.c

#include 
#include 

#include "list.h"

list *list_create(){
    list *me;
    me  = malloc(sizeof(*me));
    if(me == NULL)
        return NULL;
    me->next = NULL;
    return me;
}

int list_insert_at(list *me, int i, datatype *data){
    int j = 0;
    list *node = me, *newnode;
    
    if(i < 0 || i > DATASIZE)
        return -1;
    
    for(j = 0; j < i && node != NULL; j++){
        node = node->next;
    }
    
    if(node != NULL){
        newnode = malloc(sizeof(*newnode));
        if(newnode == NULL)
            return -2;
        newnode->data = *data;
        
        newnode->next = node->next;
        node->next = newnode;
        
        return 0;
    }
    else{
        return -3;
    }
    
}

int list_order_insert(list *me, datatype *data){
    list *p = me, node;
    
    for(p = me; p->next && p->next->data < *data; p = p->next){
        ;
    }
    
    node = malloc(sizeof(*node));
    if(node == NULL)
        return -1;
    
    node->data = *data;
    node->next = p->next;
    p->next = node;
    
    return 0;
    
}

int list_delete_at(list *, int i, datatype *data){
    int j = 0;
    list *p = me, *q;
    
    *data = -1;
    
    if(i < 0)
        return -1;
    
    while(j < i && p){
        p = p->next;
        j++;
    }
    
    if(p){
        q = p->next;
        p->next = q->next;
        free(q);
    }
    else{
        return -2;
    }
    
}

int list_delete(list *, datatype *){
    list *p = me, *q;
    
    for(p = me; p->next && p->next->data != *data; p = p->next){
        ;
    }
    
    if(p->next == NULL)
        return -1;
    else{
        q = p->next;
        p->next = q->next;
        *data = q->data;
        free(q);
        q = NULL;
        return 0;
    }
    
}

int list_isempty(list *me){
    if(me->next == NULL)
        return 0;
    return 1;
}

void list_display(list *me){
    list *node = me;
    if(list_isempty(me) == 0)
        return ;
    for(node = me->next; node != NULL; node = node->next){
        printf("%d ", node->data);
    }
    printf("\n");
    return ;
}

void list_destroy(list *me){
    list *node, *next;
    for(node = me->next; node != NULL; node = next){
        next = node->next;
        free(node);
    }
    free(me);
    return ;
}

main.c

#include 
#include 

#include "list.h"

int main(){
    
    list *l;
    l = list_create();
    if(l == NULL){
        exit(1);
    }
    
    datatype arr[] = {12,34,5,354,64};
    
    for(int i = 0; i < sizeof(arr)/sizeof(*arr); i++){
        if(list_insert_at(l, 0, &arr[i]))//if(list_order_insert(l, &arr[i]))
            exit(-1);
    }
    
    list_display(l);
    
    int value = 12;
    list_delete(l, &value);
    
    datatype v;
    int err = 0;
    err = list_delete_at(l, 2, &v);
    if(err)
        exit(1);
    list_display(l);
    printf("delete:%d\n", v);
    
    list_destroy(l);
    list_display(l);
    
    return 0;
}

2 无头单链表

  • (代码已测试通过)

makefile

all:main

main:main.o nohead.o
	$(CC) $^ -o $@
	
clean:
	rm *.o main -rf


nohead.h

#ifndef NOHEAD_H__
#define NOHEAD_H__


#define NAMESIZE    32

typedef struct score_st datatype;

struct score_st{
    int id;
    char name[NAMESIZE];
    int math;
    int chinese;
};

typedef struct node_st{
    struct score_st data;
    struct node_st *next;
}nohead;

int list_insert(nohead **, datatype *);
void list_show(nohead *);
int list_delete(nohead **);
datatype *list_find(nohead *, int id);

void list_destroy(nohead *);

#endif

nohead.c

#include 
#include 

#include "nohead.h"

int list_insert(nohead **list, datatype *data){
    nohead *new;
    new = malloc(sizeof(*new));
    if(new == NULL)
        return -1;
    new->data = *data;
    new->next = *list;
    *list = new;
    return 0;
}

void list_show(nohead *list){
    nohead *cur;
    for(cur = list; cur != NULL; cur = cur->next){
        printf("%d %s %d %d \n", cur->data.id, cur->data.name, cur->data.math,\
         cur->data.chinese);
    }
}

int list_delete(nohead **list){
    nohead *cur;
    if((*list == NULL))
        return -1;
    
    cur = *list;
    *list = (*list)->next;
    free(cur);
}

datatype *list_find(nohead *list, int id){
    nohead *cur;

    for(cur = list; cur != NULL; cur = cur->next){

        if(cur->data.id == id){
            
            return &(cur->data);
        }
    }

    return NULL;

}

void list_destroy(nohead *list){
    nohead *cur;

    if(list == NULL)
        return ;
    
    for(cur = list; cur != NULL; cur = list){
        list = cur->next;
        free(cur);
    }
}

main.c

#include 
#include 

#include "nohead.h"

int main(int argc, char const *argv[]){
    
    nohead *list = NULL;
    datatype tmp;
    int ret;
    int id_1 = 3, id_2 = 15;
    datatype *ptr;

    for(int i = 0; i < 7; i++){
        tmp.id = i;
        snprintf(tmp.name, NAMESIZE, "stu%d", i);
        tmp.math = rand() % 100;
        tmp.chinese = rand() %100;

        ret = list_insert(&list, &tmp);
        if(ret != 0)
            exit(-1);
    }

    list_show(list);
    printf("\n");
    
    ptr = list_find(list, id_1);
    if(ptr != NULL){
        printf("%d %s %d %d \n", ptr->id, ptr->name, ptr->math, ptr->chinese);
    }
    else{
        printf("Can not find!\n");
    } 
    printf("\n");

    ptr = list_find(list, id_2);
    if(ptr != NULL){
        printf("%d %s %d %d \n", ptr->id, ptr->name, ptr->math, ptr->chinese);
    }
    else{
        printf("Can not find!\n");
    } 
    printf("\n");
    
    list_delete(&list);
    list_show(list);
    printf("\n");

    list_destroy(list);

    return 0;
}

结果:

wangs7_@WangQ7:~/Cprogram/nohead$ ./main
6 stu6 90 59
5 stu5 62 27
4 stu4 49 21
3 stu3 86 92
2 stu2 93 35
1 stu1 77 15
0 stu0 83 86

3 stu3 86 92

Can not find!

5 stu5 62 27
4 stu4 49 21
3 stu3 86 92
2 stu2 93 35
1 stu1 77 15
0 stu0 83 86

3 单向循环链表

约瑟夫算法:

杀人游戏:问题描述,有8个人围坐一圈分别为1号,2号…8号,从1号开始按照某一顺序(1->2->…->8->1…)循环报数每次报到3的人会被带走枪毙,并从下一个人从新报数,直到剩下最后一个人能够存活。

问题分析:将8人围坐抽象为一个8个节点的屋头循环链表,从头结点开始一次遍历,每到第三个节点就输出该节点标号并删除该节点,直到链表只剩最后一个节点。

效果:

原环链 1 2 3 4 5 6 7 8

遍历输出 3 6 1 5 2 8

最后留下的节点 7

makefile

all:main

main:main.o josephu.o
	$(CC) $^ -o $@
	
clean:
	rm *.o main -rf

josephu.h

#ifndef JOSEPHU_H__
#define JOSEPHU_H__


typedef int datatype;

typedef struct node_st{
    datatype data;
    struct node_st *next;
}Jose;


Jose *jose_create(int n);
void jose_show(Jose *);
void jose_kill(Jose **, int n);


#endif

josephu.c

#include 
#include 

#include "josephu.h"

Jose *jose_create(int n){
    Jose *me, *newnode, *cur;
    int i = 1;

    me = malloc(sizeof(*me));
    if(me == NULL)
        return NULL;
    
    me->data = i;
    me->next = me;
    i++;
    
    cur = me;
    for( ; i <= n; i++){
        newnode = malloc(sizeof(*newnode));
        if(newnode == NULL)
            return NULL; //可能存在内存泄漏 

        newnode->data = i;
        newnode->next = me;

        cur->next = newnode;
        cur = newnode;
    }

    return me;
}


void jose_show(Jose *me){

    Jose *ptr;

    for(ptr = me; ptr->next != me; ptr = ptr->next){
        printf("%d ", ptr->data);
    }

    printf("%d\n", ptr->data);

    return ;
}

void jose_kill(Jose **me, int n){
    Jose *cur = *me, *node;
    int i;
    while(cur != cur->next){

        for(i = 1; i < n; i++){
            node = cur;
            cur = cur->next;
        }

        node->next = cur->next;
        printf("%d ", cur->data);
        free(cur);
        cur = node->next;
    }
    printf("\n");

    *me = cur;

    return ;

}

main.c

#include 
#include 

#include "josephu.h"

#define JOSE_NR 8

int main(int argc, char const *argv[]){
    
    Jose *list;
    int n = 3;
    list = jose_create(JOSE_NR);

    jose_show(list);

    jose_kill(&list, n);

    jose_show(list);

    return 0;
}

结果:

wangs7_@WangQ7:~/Cprogram/josephu$ ./main
1 2 3 4 5 6 7 8
3 6 1 5 2 8 4
7

你可能感兴趣的:(C语言,数据结构)