c语言链表的基本操作2

c语言链表的基本操作2

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

typedef int Datatype;   //如果存其他类型的数据可以在此处直接修改

typedef struct node {
    Datatype data;
    struct node *next;
}Node;

//创建结点
Node* creatNode(Datatype data) {
    Node* p = NULL;
    p = (Node*)malloc(sizeof(Datatype));    //申请内存
    if (p == NULL) {    //安全检查
        return NULL;
    }
    p->data = data;     //赋值
    p->next = NULL;
    return p;
}
//打印链表
void printList(Node* head) {
    Node* p = head;
    if (head == NULL) {
        return;
    }
    while(p != NULL) {
        printf("%d\n",p->data);
        p = p->next;
    }
    return;
}
//在一个结点后插入新结点
int insertNodeBehind(Node* p,Node* pnew) {
    if (p == NULL || pnew == NULL) {
        return -1;
    }
    if (p->next != NULL) {
        pnew->next = p->next;
        p->next = pnew;
    }
    else {
        p->next = pnew;
    }
/*其实此处直接写
    pnew->next = p->next;
    p->next = pnew;
 就可以了,因为若p->next = NULL则pnew->next = NULL*/
    return 0;
}
//结点后插入一个数据
int insertDataBehind(Node *p,Datatype data) {
    Node* pnew = NULL;
    if (p == NULL) {
        return -1;
    }
    pnew = creatNode(data);
    insertNodeBehind(p,pnew);
    return 0;
}
//返回最后末尾结点的地址
Node* findListTail(Node* phead) {
    if (phead == NULL) {
        return NULL;
    }
    while (phead->next != NULL) {
        phead = phead->next;
    }
    return phead;
}
//插入数据到链表的末尾,**是因为可能会涉及修改头指针,在没有结点的情况下
int listInsertDataAtTail(Node** phead,Datatype data) {
    Node *p = NULL;
    if (phead == NULL) {
        return -1;
    }
    if (*phead == NULL) {
        *phead = creatNode(data);
        return 0;
    }
    p = findListTail(*phead);
    insertDataBehind(p,data);
    return 0;
}
//删除后一个结点
int deleteNodeBehind(Node* p) {
    Node* temp  = NULL;
    if (p == NULL) {
        return -1;
    }
    if (p->next == NULL) {
        return 1;
    }
    temp = p->next;
    p->next = p->next->next;
    free(temp);
    return 0;
}
//返回数据为data的结点的地址
Node* findNode(Node* head,Datatype data) {
    Node* p = NULL;
    if (head == NULL) {
        return NULL;
    }
    p = head;
    while (p->data != data) {
        if (p->next != NULL) {
            p = p->next;
        }
        else {
            return NULL;    //没找到该数据为data的结点
        }
    }
    return p;
}
//改数据
int listChangeData(Node* head,Datatype oldData,Datatype newData) {
    Node* p = NULL;
    if (head == NULL) {
        return -1;
    }
    p = findNode(head, oldData);
    p->data = newData;
    return 0;
}
//返回数据为data的结点的前一个结点的地址
Node* findPrevNode(Node *head,Datatype data) {
    Node* p = NULL;
    if (head == NULL) {
        return NULL;
    }
    p = head;
    while (p->next != NULL) {
        if (p->next->data == data) {
            return p;
        }
        else {
            p = p->next;
        }
    }
    return NULL;
}
//删除链表中第一个数据为data的结点
int listDeleteData(Node** phead,Datatype data) {
    Node* p = NULL;
    Node* temp = NULL;
    if (phead == NULL || *phead == NULL) {
        return -1;
    }
    if ((*phead)->data == data) {
        temp = (*phead);
        (*phead) = (*phead)->next;
        free(temp);
        return 0;
    }
    p = findPrevNode(*phead, data);
    deleteNodeBehind(p);
    free(temp);
    return 0;
}
//销毁链表
int listDestroy(Node **phead) {
    if (phead == NULL || (*phead) == NULL) {
        return 0;
    }
    while ((*phead)->next != NULL) {
        deleteNodeBehind(*phead);
    }
    (*phead) = NULL;
    free(*phead);   //不知道此处有没有错误!
    return 0;
}
int main(int argc, const char * argv[]) {
//  创建结点,查尾,增加结点
    Node* p = NULL;
    listInsertDataAtTail(&p, 1); //调用了creatNode,findListTail,insertNodeBehind
    printList(p);

    listInsertDataAtTail(&p, 2);
    listInsertDataAtTail(&p, 3);
    listInsertDataAtTail(&p, 4);
    listInsertDataAtTail(&p, 5);

    printf("已有节点:1-2-3-4-5\n");
    printList(p);

//    删除
//    printf("删除1后面结点\n");
//    listDeleteData(&p, 1);
//    listDeleteData(&p, 3);
//    printList(p);

//    修改
    printf("修改2为20000\n");
    listChangeData(p, 2, 20000);
    printList(p);

    listDestroy(&p);
    printList(p);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值