码迷,mamicode.com
首页 > 其他好文 > 详细

listNode.c

时间:2020-03-28 14:59:45      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:previous   更新   while   序号   update   upd   情况   head   div   

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

typedef struct listNode {
    int data;
    struct listNode *nextPtr;
}LISTNODE;

void instructions   (void);
void insert_random  (LISTNODE **headPtr, int value, unsigned int* listLength);
void insertFromFile (LISTNODE **headPtr, char *fileName, unsigned int *listLength);
void updateLink     (LISTNODE **headPtr, int updateNum, int value);
void delete         (LISTNODE **headPtr, int value, unsigned int* listLength);
void printLink      (LISTNODE **headPtr, unsigned int listLength);
void insert         (LISTNODE **headPtr, int value, unsigned int* listLength);

int main(void) {
    /* 链表头指针,除了在删除整个链表和更新链表头的情况下,其他情况都不能对头指针进行修改 */
    LISTNODE *headPtr = NULL;

    /* 记录链表长度 */
    unsigned int listLength = 0;

    /* 打印菜单 */
    instructions();

    /* 用户的选择 */
    int choice;
    scanf("%u", &choice);

    //定义case 1 变量
    int insertvalue;

    //定义case 2 变量
    char fileName[20];

    //定义case 3 变量
    unsigned int updateNum;
    int update;

    //定义case 4 变量
    unsigned int deleteNum;

    while (choice != 0) {
        switch (choice) {
        case 1: //增-insert
            printf("%s", "输入你的Integer数据: ");
            scanf("%d", &insertvalue);
            insert_random(&headPtr, insertvalue, &listLength);
            break;
        case 2://添加从文件-insert from file
            printf("%s", "输入文件名: ");
            scanf("%s", fileName);
            insertFromFile(&headPtr, fileName, &listLength);
            break;
        case 3: //改-update
            printf("%s%u%s", "当前链表长度为: ", listLength, "\n输入要修改的节点和数据(eg. 1 30): ");
            scanf("%u %d", &updateNum, &update);
            if(listLength >= updateNum) {
                updateLink(&headPtr, updateNum, update);
            }else {
                puts("[-] 更新点超出链表范围");
            }
            break;
        case 4://删-delete
            printf("%s%u%s", "当前链表长度为: ", listLength, "\n输入要删除的节点:");
            scanf("%u", &deleteNum);
            if (listLength >= deleteNum){
                delete(&headPtr, deleteNum, &listLength);
            } else {
                puts("[-] 删除点超出链表长度\n");
            }
            break;
        case 5://打印
            printLink(&headPtr, listLength);
            break;
        default:
            puts("[-] Input Error!");
            break;
        }

        instructions();
        scanf("%u", &choice);
    }
}

void instructions(void) {
    puts("1 ) 添加数据,无序添加");
    puts("2 ) 从文件夹中添加数据");
    puts("3 ) 修改数据(eg. 节点序号 更新值)");
    puts("4 ) 删除数据");
    puts("5 ) 打印链表");
    printf("%s", "Input your choice:");
}

/* 无序的链表 */
void insert_random(LISTNODE **headPtr, int value, unsigned int* listLength) {
    /* 新的内存区块 */
    LISTNODE *newNode = malloc(sizeof(LISTNODE));

    LISTNODE * currentPtr = *headPtr;

    /* 检测内存是否正确分配 */
    if(newNode == NULL) {
        puts("内存不足!");
        exit(2);
    }

    /* 将数据存放至节点 */
    (*newNode).data = value;
    newNode->nextPtr = NULL;

    /* 添加区块 */
    /* 添加区块到头节点 */
    if (*headPtr == NULL) {
        *headPtr = newNode;
    }else {
        /* 添加区块到尾节点 */
        while (currentPtr->nextPtr != NULL) {
            currentPtr = currentPtr->nextPtr;
        }
        
        currentPtr->nextPtr = newNode;
    }
    (*listLength)++;;
    printf("%s%d%s", "插入节点成功,当前链表长度:", *listLength, "\n\n");
}

/* 从文件中读取数据 */
void insertFromFile(LISTNODE **headPtr, char *fileName, unsigned int *listLength) {
    FILE *dataFile = fopen(fileName, "r");

    if(dataFile == NULL) {
        printf("%s%s%s", "要打开的文件是: ", fileName, "\n");
        puts("[-] 文件打开失败,程序退出");
        exit(6);
    }

    int value;

    while (!feof(dataFile)) {
        fscanf(dataFile, "%d", &value);
        printf("%s%d%s", "读取数据: ", value, "\n");

        insert_random(headPtr, value, listLength);
    }
    
    fclose(dataFile);
}

/* 更新一个节点的数据 */
void updateLink(LISTNODE **headPtr, int updateNum, int value) {
    LISTNODE *currentPtr = *headPtr;

    int loop = 1;
    while(loop < updateNum) {
        currentPtr = currentPtr->nextPtr;
        loop++;
    }

    if(currentPtr != NULL) {
        currentPtr->data = value;
    }else {
        puts("[-] 超出链表范围");
        exit(3);
    }
}

/* 删除一个区块 */
void delete(LISTNODE **headPtr, int value, unsigned int* listLength) {

    LISTNODE *currentPtr = *headPtr;

    if (value == 1) {
        /* 要删除的节点 */
        LISTNODE *delNode = NULL;
        /* 获取要删除的节点 */
        delNode = currentPtr;
        /* 更新头指针 */
        *headPtr = currentPtr->nextPtr;
        /* 删除节点 */
        free(delNode);
    }else {
        /* 要删除节点的上一个区块 */
        LISTNODE *previousPtr = NULL;

        int loop = 1;
        /* 移动到待删除点 */
        while (loop < value) {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
            loop++;
        }
        // delNode = currentPtr;
        /* 上层指针的nextPtr指向要删除节点的下一个节点 */
        previousPtr->nextPtr = currentPtr->nextPtr;
        /* 删除节点 */
        free(currentPtr);
    }

    (*listLength)--;
    printf("%s%d%s", "删除节点成功,当前链表长度:", *listLength, "\n\n");
}

/* 打印链表 */
void printLink(LISTNODE **headPtr, unsigned int listLength) {
    LISTNODE *currentPtr = *headPtr;

    printf("%s%d\n", "当前链表长度: ", listLength);
    puts("+-------------------------+");

    while (currentPtr != NULL) {
        printf("%s%d\n%s%p\n", "数据: ", currentPtr->data, "下一个节点: ", currentPtr->nextPtr);
        puts("+-------------------------+");
        currentPtr = currentPtr->nextPtr;
    }

    puts("");
}

/* 升序的链表 */
void insert(LISTNODE **headPtr, int value, unsigned int* listLength) {
    /* 新的内存区块 */
    LISTNODE *newNode = malloc(sizeof(LISTNODE));
    /* 插入新区块后指向的上一个指针 */
    LISTNODE *previousPtr = NULL;
    /* 当前指针,最后将指向待删除点的下一个节点 */
    LISTNODE *currentPtr = *headPtr;

    /* 检测内存是否正确分配 */
    if(newNode == NULL) {
        puts("内存不足!");
        exit(2);
    }

    /* 将数据存放至节点 */
    /* 两种都行 */
    (*newNode).data = value;
    newNode->nextPtr = NULL;

    /* 移动到待插入点,头节点时previousPtr为空,尾节点时nextPtr为空 */
    /* !!不可将判断顺序对调!! */
    while(currentPtr != NULL && value > currentPtr->data){
        previousPtr = currentPtr;
        currentPtr = currentPtr->nextPtr;
    }

    /*  添加区块
        如果上层指针为空,则插入点为头节点
        插入中间节点和尾节点是一样的 */
    if (previousPtr == NULL) {
        /* 新区块的nextPtr指向原来的链表头 */
        newNode->nextPtr = *headPtr;
        /* 更新头指针 */
        *headPtr = newNode;
    }else {
        previousPtr->nextPtr = newNode;
        newNode->nextPtr = currentPtr;
    }
    (*listLength)++;
    printf("%s%d%s", "插入节点成功,当前链表长度:", *listLength, "\n\n");
}

 

listNode.c

标签:previous   更新   while   序号   update   upd   情况   head   div   

原文地址:https://www.cnblogs.com/zhaoritian12138/p/12587384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!