数据结构学习笔记-02循环链表

253 阅读3分钟
#include <stdio.h>
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"

#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /*存储空间初始化分配量*/

//定义返回结果
typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Element;/* Element类型根据实际情况而定,这里假设为int */

//定义结点
typedef struct Node {
    Element data;
    struct Node *next;
}Node;

typedef struct Node * Linklist;

//循环链表的创建
Status creatList(Linklist *L) {
    int item;
    Linklist temp =  NULL;
    Linklist target = NULL;
    printf("请输入新的结点, 当输入0时结束!\n");
    
    
    while (1) {
        scanf("%d",&item);
        if (item == 0) {
            break;
        }
        
        /*
         如果是链表为空,那就创建;如果不为空,那就使用尾插法插入
         */
        if (*L == NULL) {
            //创建结点
            *L = (Linklist)malloc(sizeof(Node));
            if (*L == NULL) {//创建成功,退出创建程序;容错判断
//                return ERROR;
                exit(0);
            }
            //赋值
            (*L)->data = item;
            //将next 指向自己
            (*L)->next = *L;
        } else {
            //尾插法插入结点
            
            //链表不为空,就先寻找尾结点
            for (target = *L; target->next != *L; target = target->next);
            temp = (Linklist)malloc(sizeof(Node));
            if (temp == NULL) {
                return ERROR;
            }
            temp->data = item;//数据赋值
            
            target->next = temp;//尾结点指向新结点
            temp->next = *L;//新节点指向头结点
        }
    }
    return OK;
}

//遍历链表
Status show(Linklist L) {
    if (L == NULL) {
        printf("打印的聊表为空!\n");
        return ERROR;
    } else {
        Linklist target;
        target = L;
        do {
            printf("%5d",target->data);
            target = target->next;
        } while (target != L);//当target == L 时遍历结束
        printf("\n");
        return OK;
    }
}

// 增
Status insertData(int place,Element data,Linklist *L) {
    Linklist temp,target;
    if (place == 1) {//如果插入的位置是第一个
        //1. 创建新结点temp,并判断是否创建成功,成功则赋值,否则返回ERROR;
        temp = (Linklist)malloc(sizeof(Node));
        if (temp == NULL) {
            return ERROR;
        }
        temp->data = data;
        
        //2.找到尾节点
        for (target = *L; target->next != *L; target = target->next);
        
        //3.让新结点的next 指向头结点.
        temp->next = *L;
        
        //4.尾结点的next 指向新的头结点;
        target->next = temp;
        
        //5.让头指针指向temp(临时的新结点)
        *L = temp;
    } else {//插入的不是第一个
        //1. 创建新结点temp,并判断是否创建成功,成功则赋值,否则返回ERROR;
        temp = (Linklist)malloc(sizeof(Node));
        if (temp == NULL) {
            return ERROR;
        }
        temp->data = data;
        
        //2.找要插入位置的前一个结点;如果超过链表长度,则自动插入队尾;
        int i;
        for (i = 1,target = *L; target->next != *L && i != place-1; target = target->next,i++);
        
        //3.先将target->next 继承到temp->next,防止丢失
        temp->next = target->next;
        //4.再将temp继承到target->next
        target->next = temp;
    }
    return OK;
}

//删除
Status deleteData(Linklist *L,int place) {
    Linklist temp,target;
    
    //temp 指向链表首元结点
    temp = *L;
    
    if (temp == NULL) {
        return ERROR;
    }
    
    if (place == 1) {
        //如果删除到只剩下首元结点了,则直接将*L置空;
        if (temp->next == temp) {
            *L = NULL;
            return OK;
        }
        
        //如果还有其他的
        //1.找到尾节点
        for (target = *L; target->next != *L; target = target->next);
        
        //2.将*L换成第二个
        *L = temp->next;
        
        //3.将尾指针指向第二个
        target->next = temp->next;
        
        //4.释放temp
        free(temp);
    } else {
        //如果删除其他结点--其他结点
        
        //1. 找到删除结点前一个结点target
        int i;
        for (i = 1,target = *L; target->next != *L && i != place-1; target = target->next,i++);
        //2. 使得target->next 指向下一个结点
        temp = target->next;
        target->next = temp->next;
        
        //3. 释放需要删除的结点temp
        free(temp);
    }
    return OK;
}

//查
Status findValue(Linklist L,int place,Element *pData) {
    Linklist temp,target;
    
    //temp 指向链表首元结点
    temp = L;
    
    if (temp == NULL) {
        return ERROR;
    }
    
    if (place == 1) {
        //如果是第一个
        *pData = temp->data;
        return OK;
    } else {
        //如果删除其他结点--其他结点
        
        //1. 找到目标结点target
        int i;
        for (i = 1,target = L; target->next != L && i != place; target = target->next,i++);
        *pData = target->data;
    }
    return OK;
}


int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    Linklist pList;
    int place,num;
    Status pStatus;
    
    pStatus = creatList(&pList);
    show(pList);
    
    printf("输入要插入的位置和数据用空格隔开:");
    scanf("%d %d",&place,&num);
    pStatus = insertData(place, num, &pList);
    show(pList);

    printf("输入要删除的位置:");
    scanf("%d",&place);
    deleteData(&pList, place);
    show(pList);
    
    
    Element pData;
    int p = 3;
    pStatus = findValue(pList, p, &pData);
    printf("位置 %d :%d \n",p,pData);
    
    return 0;
}