数据结构之单链表与循环链表

一、链表的结构表示

(一)相关术语:

1.节点:数据元素的存储映像。由数据域和指针域两部分组成。
2.链表:n个节点由指针域组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构

单链表的结构:

typedef struct Lnode{    //声明结点的类型和指向节点的指针类型
    ElemType data        //结点的数据域
    struct Lnode *next   //结点的指针域
}Lnode, *LinkList        //LinkList 为指向结构体Lnode的指针类型

(二)单链表的相关操作:

1.链表的初始化

Status InitList_L(LinkList &L){   //
    L = new LNode                 // 生成新的结点作头结点,用头指针L指向头结点
    L->next = NULL                // 将头节点的指针域置空
    return OK                     // 
}

2.判断链表是否为空

int ListEmpty(LinkList L) {  //如果为空表,返回1否则返回0
    if(L->next) {    //非空 
    return 0 
    } else {
    return 1        //
    }
}

 3.销毁单链表L

Status DestroyList_L(LinkList &L) {  //销毁单链表
    Lnode *p                         // 定义一个变量用于储存单链表的后续 ,其中L、P都是指针,存储的地址,
    while (L) {                      // 循环遍历直到为空
    P = L                            // 将L存储的地址赋值给P
    L = L->next                      // L取到下一个链表的地址
    delete P                        // 销毁P地址指向的内容
    }
}

4.清空单链表(清空内容,但是链表仍然存在)
 

Status DestroyList_L(LinkList &L) {  // 清空单链表
    Lnode *p ,*q                     // 因为要保留头节点,需要定义两个指针变量,一个存储需要销毁的结点,一个存储销毁的下一个结点
    p = L->next                      // 从L.next开始清除,保留头节点
    while (P) {                      // 没到尾节点
    q=p->next                        // 保留下一结点链表的位置     
    delete P                         // 消除p的位置    
    p = q                            // 重新赋值
    }
    L->next = NULL                   // 便利完除头节点,其余结点已经全部消除,将头结点的指针域赋值为空
    return OK
}

 5.求链表L的表长

int ListLength_L(LinkList L) {
    LinkList p
    p = L->next
    i=0
    while(p) {
    i++
    p =p->next
    }
    return i
}

6.单链表的取值 

Status GetElem_L (LinkList L,int i,ElemType &e) {    //获取线性表L中的某个数据元素的内容,通过变量e返回
    p = L->next ; j=1                                //   初始化
    while(p && j<1) {                                //向后变量除非达到第i个的位置,并且p存在
    p=p->next; ++j                                   
    }
    if(!p || j>i) return ERROR                       //判断第i个元素是否存在
    e=p->data                                        //取第i个元素
    return OK    
}// GetElem_L

7.单链表的查找

Lnode *LocateElem_L (LinkList L,Elemtype e) {
    //在线性表L中查找值为e的数据元素
    //找到返回L中值为e的数据元素的地址,否则返回null
    p = L->next;
    while(p && p->data != e){
        p = p->next
    }
    return P
}

8.单链表的插入操作

Status ListInsert_L (LinkList &L.int i, ElemType e) {  //在l中第i个元素之前插入数据元素e
    p = L;j = 0;
    while (p && j<i-1) {                               // 寻找第i-1个结点,p指向i-1结点
    p=p->next;                                         
    ++j
    }  
    s = new Lnode;                                     //生成新结点s,将结点s的数据置为e
    s->data = e
    s->next = p->next                                  //将结点i-1的next赋值给插入结点
    p->next = s                                        //将插入结点赋值给i-1的next
    return OK
}

9. 单链表的删除操作

Status ListDelete_L (LinkList &L.int i, ElemType &e) {  //在L中删除第i个元素
    p = L;j = 0;q=0;
    while (p->next && j<i-1) {                               // 寻找第i-1个结点,p指向i-1结点
    p=p->next;                                                 
    ++j
    }
    if(!(p->next)||j>i-1) return ERROR                 //判断删除位置是否合理
    q=p->next                                          //找到第i个结点的位置
    p->next = q->next                                  //将第i+1个结点的位置赋值给i-1的next
    e = q->data                                        //保存删除结点的数据域
    delete q                                           //释放结点的空间
    return OK
}

10.单链表的的建立

1.头插法(从最后一个结点开始,依次将各结点插入到链表的前端)
void CreateList_H(LinkList &L, int n) {
    L = new LNode
    L->next = NULL               // 创建一个头结点
    for (i = n, i>0, --i) {
    p = new LNode                // 生成新结点 p
    cin>>p->data                 // 输入元素值 
    p->next = L->next            // 将头结点的next赋值给新结点
    L->next = p                  // 将新结点赋值给头结点的next
    }
}

2.尾插法(元素插入在链表尾部)
void CreateList_R(LinkList &L, int n) {
    L = new LNode
    L->next = NULL               // 创建一个头结点
    r = L                        // 尾指针r指向头结点
    for (i = 0, i<n, ++i) {
    p = new LNode                // 生成新结点 p
    cin>>p->data                 // 输入元素值 
    p->next = NULL               // 将头结点的next赋值给新结点
    r->next = p                  // 将新结点赋值给头结点的next
    }
}

(三)循环链表

1.循环链表的概论

由于循环列表中尾指针的next指向了头指针,所以没有NULL指针,在涉及遍历的时候,其终止条件就不再非循环链表那样判断p或p->next是否为空,而是判断它们是否等于头指针

2.链表的合并

//合并尾指针的两个循环链表
LinkList Connect(LinkList Ta, linkList Tb) {
    p = Ta->next                                //p存表头结点
    Ta->next = Tb ->next->next                  //Tb 表头链接Ta 表头
    delete Tb->next                             // 释放Tb表头结点
    Tb->next = p                                //修改指针
    return Tb
}

 

posted @   铜须的编程生活  阅读(318)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示