带头节点的C语言单链表增删改查,头插法尾插法

接上篇顺序表,这篇写的是带头节点的单链表

# include "stdlib.h"
# include "stdio.h"

# define OK 1
# define ERROR 0

typedef int Status;//自定义数据类型 相当于int仅用作装逼
//实现一个带头节点的单链表

//节点类
typedef struct LNode{
    int data;//传说中的数据域    结构体A.next    指针 A->next
    struct LNode *next;//传说中的指针域
}LNode;

//头插法建立单链表
LNode* headInitList(int A[]){
    /**在函数中获取传入的数组的实际长度的奇技淫巧。。。
     * 方法一,长得丑了点,但是很好理解,而且可以判断空的数组,不用减
     * int len;
     * for (int i = 0; *(A+i) != '\0'; ){
     *         i++;
     *         len = i;
     *     };
     * 方法二,忘记了在哪里看到了学来的
     * ++len 没有判断A[0]的值,不适用于空的数组  意思是先自加再应用到A+len
     * len++ 可以判断A[0]是否为空,可用于空的数组,要在最后结束了让len-1才是真实的数组长度
     * 
     * 如果传入了一个空的数组,那就只返回一个头结点就好了
    */
    int len = 0;
    while(*(A+(len++))!='\0');
    len--;    
    LNode *head = (LNode*)malloc(sizeof(LNode));
    /*这里一定要记得将头结点的next置空*/
    head->next = NULL;
    for (int i = len; i > 0; i--)
    {
        LNode *new  = (LNode*)malloc(sizeof(LNode));
        new->next = head->next;
        new->data = A[i-1];
        head->next = new;
    }
    printf("头插法建立单链表成功\n");
    return head;
}

//尾插法建立单链表
LNode* tailInitList(int A[]){
    int len = 0;
    while(*(A+(len++))!='\0');
    len--;
    LNode *head = (LNode*)malloc(sizeof(LNode));
    head->next = NULL;
    LNode *tail = head;
    for (int i = 0; i < len; i++)
    {
        LNode *new = (LNode*)malloc(sizeof(LNode));
        new->data = A[i];
        new->next = NULL;
        tail->next = new;
        tail = tail->next;
    }
    printf("尾插法建立单链表成功\n");
    return head;
    
}

//初始化一个单链表,返回头结点
LNode* InitList(){
    LNode *head = (LNode*)malloc(sizeof(LNode));
    if(head){
        head->next = NULL;
        printf("单链表初始化成功\n");
        return head;
    }
}
//按位取元素
Status GetElem(LNode *L ,int n){
    int i = 0;
    LNode *p = L;
    while (p->next){
        p = p->next;
        i++;
        if (i == n)
        {
            printf("单链表中第%d个元素中data=%d\n",n,p->data);
            return OK;
        }
    }
    printf("当前单链表中共有%d个元素,你输入的数值%d错误\n",i,n); 
    return ERROR;   
}

// //查找元素
Status LocateElem(LNode *L, int e){
    int i = 0;
    LNode *p = L;
    while (p->next){
        p = p->next;
        i++;
        if(p->data== e){
            printf("你要查找的元素位于单链表中第%d位\n",i);
            return OK;
        }
    }
    printf("你要查找的元素不存在\n");
    return ERROR;
}

// 插入元素
Status ListInsert(LNode *L, int n, int e){
    LNode *p =L;
    int i = 0;
    while (p->next)
    {
        p = p->next;
        i++;
        if (n == i)
        {
            LNode *q = (LNode*)malloc(sizeof(LNode));
            q->data = e;
            q->next = p->next;
            p->next = q;
            printf("元素插入成功");
            return OK;
        }
    }
    if (n == i+1){
        LNode *q = (LNode*)malloc(sizeof(LNode));
        q->data = e;
        q->next = p->next;
        p->next = q;
        printf("元素插入成功\n");
        return OK;
    }
    printf("元素插入失败,当前共有%d个元素,你想插入的位置%d不正确\n",i,n);
}

// //删除元素
Status ListDelete(LNode *L, int n){
    int i = 0;
    LNode *p = L;
    LNode *temp;
    while (p->next)
    {
        i++;
        if (n==i)
        {
            temp = p->next;
            p->next = temp->next;
            free(temp);
            printf("删除元素%d成功\n", i);
            return OK;
        }
        p = p->next;
    }
    printf("当前单链表共%d个元素,你想删除的元素%d不存在\n",i,n);
    return ERROR;     
}

//遍历单链表
Status ListPrint(LNode *L){
    LNode *p = L;
    while (p->next)
    {
        p = p->next;
        printf("data:%d\n",p->data);
    }
    return OK;
}

// //查看表长
Status ListLength(LNode *L){
    int i = 0;
    LNode *p = L;
    while (p->next)
    {
        p = p->next;
        i++;
    }
    printf("单链表的长度是%d\n",i);
    return OK;
}

// //清空单链表
Status ListClear(LNode *L){
    LNode *temp;
    LNode *p = L;
    while (p->next)
    {
        temp = p->next;
        p->next = temp->next;
        free(temp);
    }
    printf("单链表已经清空\n");
    return OK;
}

// //判断单链表是否为空
Status ListEmpty(LNode *L){
    LNode *p = L;
    if (p->next)
    {
        printf("单链表不为空\n");
        return ERROR;
    }
    printf("单链表为空\n");
    return OK;
}

//销毁单链表
Status ListDestroy(LNode *L){
    ListClear(L);
    free(L);
    printf("单链表已销毁");
    return OK;
}

int main(int argc, char const *argv[])
{
    // LNode *L = InitList();
    // ListInsert(L,1,1);
    // ListInsert(L,2,2);
    // ListInsert(L,2,3);
    // ListInsert(L,5,3);
    // ListDelete(L,1);
    // ListPrint(L);
    // ListLength(L);
    // ListEmpty(L);
    // ListClear(L);
    // ListEmpty(L);
    // ListLength(L);
    // ListDestroy(L);
    
    //测试头插法建立单链表
    // int A[6] = {1,2,3,4,5};  //这里故意就弄五个只为了测试上面的数组长度算法
    // LNode *L = headInitList(A);
    // ListPrint(L);
    //测试尾插法建立单链表
    int A[6] = {1,2,3,4,5};
    LNode *L = tailInitList(A);
    ListPrint(L);
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值