vanity_chang 发表于 2020-2-20 14:26:54

单向链表,用函数实现各功能

代码如下,有不足的地方希望能提出在帖子下方
#include <stdio.h>
#include <string.h>
#include <malloc.h>

#define OBJECT char name[]
#define null NULL
#define IndexOutBounds(index) printf("不合法的索引位置:%d!\n", index)

#define MALLOC (NODE *) malloc(sizeof(NODE))

typedef struct node NODE;
typedef struct node * NODEP;

struct node{
        char name;
        NODE *p;
};

static int size = 0;
static NODE *first = null;
static NODE *last = null;
static NODE nullNode = {"", null};

NODEP getNode(OBJECT){
        NODEP p = MALLOC;
        int i = 0;
        while((p -> name) = name){}
        p -> p = null;
        return p;
}

void add(OBJECT){
        NODEP node = getNode(name);
        void toString();
        size++;
        if(!last){
                first = node;
                last = first;
                return;
        }
        last -> p = node;
        last = last -> p;
}

void addFirst(OBJECT){
        NODEP node = getNode(name);
        void toString();
        size++;
        if(!first){
                first = node;
                last = first;
                return;
        }
        node -> p = first;
        first = node;
}

void addTo(OBJECT, int index){
        int checkIndex(int index);
        NODEP get(int index);
        NODEP temp;
        NODEP node = getNode(name);
        if(index == 0){
                addFirst(name);
        }else if(index == size){
                add(name);
        }else{
                if(checkIndex(index)){
                        size++;
                        temp = get(index - 1);// 查询出要插入位置的上一个节点
                        node -> p = temp -> p;// 将新节点的下一节点改为上一节点的下一节点
                        temp -> p = node;// 将上一节点的下一节点改为新节点
                }
        }
}

int empty(){
        return size == 0;
}

// 检查索引是否合法
int checkIndex(int index){
        if(index < 0 || index >= size){
                IndexOutBounds(index);
                return 0;
        }
        return 1;
}

NODEP get(int index){
        int i = 0;
        NODEP node = null;
        // 判断索引是否越界
        if(checkIndex(index)){
                node = first;
                for(; i < size - 1; i++){
                        if(i == index){
                                return node;
                        }
                        node = node -> p;
                }
        }
        return node;
}

void removeFirst(){
        NODEP p = first;
        size--;
        if(size == 1){
                first = null;
                last = null;
                free(p);
                return;
        }
        first = first -> p;
        free(p);
}

void removeLast(){
        NODEP temp;
        NODEP p = last;
        size--;
        if(size == 1){
                first = null;
                last = null;
                free(p);
                return;
        }
        temp = get(size - 2);
        temp -> p = null;
        last = temp;
        free(p);
}

void removeNode(int index){
        NODEP temp;
        if(checkIndex(index)){
                if(index == 0){
                        removeFirst();
                }else if(index == size - 1){
                        removeLast();
                }else{
                        NODEP p;
                        size--;
                        temp = get(index - 1);
                        p = temp -> p;
                        temp -> p = temp -> p -> p;
                        free(p);
                }
        }
}

void toString(){
        if(size == 0){
                printf("[]\n");
                return;
        }
        {
                NODEP node = first;
                char string = "[";
                strcat(string, node -> name);
                while(node -> p){
                        node = node -> p;
                        strcat(string, ",");
                        strcat(string, node -> name);
                }
                strcat(string, "]");
                printf("%s\n", string);
        }
}

void main(){
        int i;
        char name;
        while(i != 5){
                printf("----------------------------------------\n1.添加\n2.删除\n3.查询\n4.展示\n5.退出\n");
                scanf("%d", &i);
                if(i < 1 || i > 5){
                        i = 1;
                }
                switch(i){
                case 1 : {
                                        printf("1.最前面\n2.最后面\n3.指定位置\n");
                                        scanf("%d", &i);
                                        printf("请输入姓名:\n");
                                        scanf("%s", &name);
                                        if(i == 1){
                                                addFirst(name);
                                        }else if(i == 2){
                                                add(name);
                                        }else{
                                                printf("输入要插入的位置:\n");
                                                scanf("%d", &i);
                                                addTo(name, i);
                                        }
                                        break;
                               };
                case 2 : {
                                        printf("输入要删除的位置:\n");
                                        scanf("%d", &i);
                                        removeNode(i);
                                        break;
                               };
                case 3 : {
                                        printf("输入要查询的位置:\n");
                                        scanf("%d", &i);
                                        printf("%s\n", get(i) -> name);
                                        break;
                               };
                case 4 : {
                                        toString();
                                        break;
                               };
                case 5 : goto end;
                }
        }
end:;
}
页: [1]
查看完整版本: 单向链表,用函数实现各功能