• 线性表的顺序存储实现(二)单链表、双链表、循环链表


    单链表

    带头结点

    初始化

    // 带头结点的单链表
    
    bool InitList_head(LinkList &L)
    {
        L = (LNode *)malloc(sizeof(LNode)); // 分配一个头节点
        if (L == NULL)
        {
            return false; // 内存不足,分配失败
        }
        L->next = NULL; // 头结点之后还没节点
        return true;
    }
    

    空链判断

    bool Empty_head(LinkList L)
    {
        if (L->next == NULL) // 只有一个头结点的 “带头结点的单链表” => 空表
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    按位序插入

    bool ListInsert(LinkList &L, int i, int e) // 按位序插入
    {
        if (i < 1)
        {
            return false;
        }
        LNode *p;  // 指针p指向当前扫描到的节点
        int j = 0; // 当前p指向的是第几个节点
        p = L;
        while (p != NULL && j < i - 1) // 遍历链表找到第i-1个节点
        {
            p = p->next;
            j++;
        }
        if (p == NULL) // i值不合法 插到无前驱也无后继的位置
        {
            return false;
        }
    
        LNode *s = (LNode *)malloc(sizeof(LNode)); // 申请一个新的节点空间
        s->data = e;
        s->next = p->next; // s 指向第i个元素
        
        p->next = s; // 第i-1个元素指向 s
    
        return true;
    }
    

    某结点前插入

    bool InsertPrioNode(LNode *p, int e) // 在指定节p点前插入元素 e  // 思路:先插到p之后,再交换p存的值p->data与新节点存的值e
    {
        if( p==NULL )
        {
            return false;
        }
        LNode *s = (LNode *)malloc(sizeof( LNode ));
        if( s==NULL )
        {
            return false;
        }
        s->next = p->next;  // s 插入到 p 后面
        p->next = s;
        s->data = p->data;  // p s 互换data
        p->data = e;
    
        return true;
        
    }
    

    某结点后插入

    bool InsertNextNode(LNode *p, int e) // 在指定节点p后插入元素 e
    {
        if(p == NULL)
        {
            return false;
        }
        LNode *s = (LNode *)malloc(sizeof(LNode));
        if(s == NULL) // 内存分配失败
        {
            return false;
        }
        s->data = e;
        s->next = p->next; // s 指向 p的下一个节点
        p->next = s; // p 指向 s
    
        return true;
    }
    

    按位序删

    bool ListDelete(LinkList &L, int i, int &e)  // 按位序删除
    {
        if( i<1 )
        {
            return false;
        }
        LNode *p;  // 指向当前扫描到的节点
        int j = 0;  // 当前节点位序
    
        p = L;
        while( p!=NULL && j<i-1 )  // 循环到 j = i-1;
        {
            p = p->next;
            j++;
        }
        if( p==NULL )  // 位置 i 不合法
        {
            return false;
        }
        if( p->next == NULL )  // 不存在第 i 位元素
        {
            return false;
        }
        LNode *q = p->next;
        e = q->data;
        p->next = q->next;
    
        free(q);
        return true;
    
    }
    
    

    删除指定结点

    bool DeleteNode(LNode *p)  // 删除指定节点  // 思路:*p 与其后继 q 互换值, 删掉后继节点 q, 但
    {
        if( p==NULL )
        {
            return false;
        }
        LNode *q = p->next;  // q 指向 *p 的后继节点  
        
        p->data = p->next->data;
        p->next = q->next;  // 将 q 节点从链中断开
        free(q);
    
        return true;
    
    }
    

    按位序查找

    LNode * GetElem(LinkList &L, int i) // 按位查找 返回第i位元素
    {
        if (i < 1)
        {
            return NULL;
        }
        LNode *p;  // 指针p指向当前扫描到的节点
        int j=0;   // 当前p指向的是第几个节点
        p = L;
        while (p != NULL && j < i) // 遍历链表找到第 i 个节点
        {
            p = p->next;
            j++;
        }
        // if (p == NULL) // i值不合法 -> p退出时正好时 NULL
        // {
        //     return NULL;
        // }
    
        return p;
    }
    

    按值查找

    LNode * LocateElem( LinkList L, int e )  // 按值查找
    {
        LNode *p = L->next;  // 从第 1 个元素开始查找
        while( p != NULL && p->data != e)  // 循环到值为e的节点 p
        {
            p = p->next;
        }
        
        return p;
    }
    

    链表长度

    int Length(LinkList L)
    {
        int len = 0;  // 统计表长
        LNode *p = L;
        while( p->next != NULL )
        {
            p = p->next;
            len++;
        }
    
        return len;
    }
    

    打印链表

    void PrintLink( LinkList L )
    {
        printf("Length: %i \n", Length(L));
    
        LNode *p;
        int t=0; // 记录位序
        p = L->next;  // 从头结点之后开始打印
    
        printf("HeadNode ->");
        while( p != NULL )
        {
            t++;
            printf(" %i -> ", p->data);
            p = p->next;
        }
        puts(" NULL\n");
    }
    

    主函数(用于测试)

    int main()
    {
        // 创建单链表
        LinkList L;
        InitList_head(L);
        PrintLink(L);
    
    
        // 按位序插入
        for(int i=0; i<5; i++)
        {
            ListInsert(L, i+1, i+1); 
        }
        PrintLink(L);
        // 在某节点后插入
        LNode *np;
        np = L->next;
        InsertNextNode(np, 100);
        printf("insert next node successful... node->data: %i\n", np->next->data);
        PrintLink(L);
        // 在某节点前插入
        LNode *pp;
        pp = L->next;
        InsertPrioNode(pp, 100);
        printf("insert prio node successful... node->data: %i\n", pp->next->data);
        PrintLink(L);
    
        // 按位序删除
        int e;
        ListDelete(L, 3, e);
        printf("del NO.3 %i successful...\n", e);
        PrintLink(L);
        // 删指定节点
        LNode *dp;
        dp = L->next;
        DeleteNode(dp);
        printf("del node  successful... NOW node->data=%i \n", dp->data);
        PrintLink(L);
    
    
    
        // 按位序查找
        LNode *p;
        p = GetElem(L, 3);
        printf("GetElem NO.3 : %i\n", p->data);
    
        // 按值查找
        LNode *q;
        q = LocateElem(L, 4);
        printf("LocateElem 4 :  q->data = %i\n", q->data);
    
    
        return 0;
    
    
        
    }
    

    测试结果

    image

    不带头结点

  • 相关阅读:
    MySQL数据库返回影响行数的实际操作流程
    nslookup命令
    Mysql Strict Mode
    mysql表大小写
    Objective-C消息转发
    NSDateFormatter 和 NSDateComponents 的用法
    提交app的时候总是报出icon的错误
    IOS 的loadView 及使用loadView中初始化View注意的问题。(死循环并不可怕)
    [[NSMutableArray alloc] init];和[[NSMutableArray alloc] initWithCapacity:0]区别
    NSMutableArray初始化崩溃问题
  • 原文地址:https://www.cnblogs.com/hugboy/p/16265145.html
Copyright © 2020-2023  润新知