单链表:创建、判空表、计算长度、销毁链表、清空链表、取第i个位置的值、单链表的查找(返回地址、位序)、在第i个元素前插入值为e的结点、删除单链表、头插法建立单链表、遍历单链表、尾插法建立单链表


 

 

 

当链表的每个结点只包含一个指针域时,我们称此链表为单链表。

关于单链表的存取,有时候我们在单链表的第一个结点(有效元素)之前附设一个结点,称之为头结点;指向头结点的指针,称之为头指针;对单链表的存取必须从头指针开始进行,由于单链表的最后一个数据元素没有直接后继,则指针为NULL。

 

 

 

 

 

 

对于头结点,数据域可以不存储任何信息,也可存储如链表长度等附加信息。

下面是带头结点的单链表与空表的比较图。

 

 

头指针与头结点不同,头结点即第一个结点,头指针是指向第一个结点的指针。链表中可以没有头结点,但不能没有头指针。

关于头指针:

  • 在线性表的链式存储结构中,头指针是指链表指向第一个结点的指针,若链表有头结点,则头指针就是指向链表头结点的指针。
  • 头指针具有标识作用,故常用头指针冠以链表的名字。
  • 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。

关于头结点:

  • 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。
  • 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。
  • 首元结点也就是第一个元素的结点,它是头结点后边的第一个结点。
  • 头结点不是链表所必需的。

 

 

 

 

 

头插法建立单链表:

 

 

 尾插法建立单链表:

 

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "iostream"
using namespace std;


#define ListSize 10

//单链表的创建
typedef struct LNode {
    int data;//数据域
    struct LNode *next;//链接域
}LNode,*Linklist;

//单链表的初始化
bool InitList(Linklist &L)
{
    L = new LNode;//创建一个新的结点作为头结点,用头指针L指向头结点
    L->next = NULL;//让头结点的指针域为空

    return true;
}

//判断单链表是否为空表:指针域那边为空
bool ListEmpty(Linklist L)
{
    if (L->next)
        return false;
    else
        return true;
}

//销毁单链表---不保留头结点
bool DestroyList(Linklist &L)
{
    LNode *p;
    while (L)
    {
        p = L;
        L = L->next;
        delete p;
    }
    return true;
}

//清空单链表---保留头指针和头结点,头结点的指针域要置为空
bool DeleteList(Linklist &L)
{
    LNode *p, *q;
    p = L->next;
    while (p)
    {
        q = p->next;
        delete p;
        p = q;
    }
    L->next = NULL;
    return true;
}

//求单链表的表长
int ListLength(Linklist L)
{
    int i = 0;
    LNode *p;
    p = L->next;
    while (p)
    {
        p = p->next;
        i++;
    }
    return i;
}

//取第i个元素的值
bool GetElem(Linklist L, int i, int &e)
{
    LNode *p;
    p = L->next;
    int j = 1;
    while (p && j<i)
    {
        p = p->next;
        j++;
    }
    //查找到最后的情况以及i可能为负数的情况
    if (!p || j > i)
        return false;
    e = p->data;
    return true;
}

//单链表的查找---查找某个元素值,返回该元素的地址
LNode *LocateElem(Linklist L, int e)
{
    LNode *p;
    p = L->next;
    while (p && p->data != e)
    {
        p = p->next;
    }
    return p;
}

//单链表的查找---查找某个元素值,返回该元素的序号
int LocateElemInt(Linklist L, int e)
{
    LNode *p;
    p = L->next;
    int i = 1;
    while (p && p->data != e)
    {
        p = p->next;
        i = i + 1;
    }
    if (p)
        return i;
    else
        return 0;
}

//单链表的插入---在第i个结点前插入值为e的结点(需要找第i-1个结点)
bool ListInsert(Linklist &L, int i, int e)
{
    LNode *p, *s;
    p = L;
    int j = 0;
    while (p && j < i - 1)
    {
        p = p->next;
    }
    if (!p || j > i-1)
        return false;
    s = new LNode;
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;
}

//单链表的删除---删除第i个结点,需要找到第i-1个结点
bool DeleteList(Linklist &L, int i, int &e)
{
    LNode *p, *q;
    int j = 0;
    p = L;
    while (p && j < i - 1)
    {
        p = p->next;
    }
    if (!(p->next) || j > (i-1))
        return false;
    q = p->next;
    e = q->data;
    p->next = p->next->next;
    delete q;
    return true;
}

//头插法建立单链表
void CreatList_H(Linklist &L, int n)
{
    L = new LNode;
    L->next = NULL;
    for (int i = n; i > 0; i--)
    {
        LNode *p = new LNode;//建立新结点
        cin >> p->data;//读入数据
        p->next = L->next;
        L->next = p;
    }
    cout << "创建长度为" << n << "的单链表完毕!"<<endl;
}

//尾插法建立单链表
void CreatList_R(Linklist &L, int n)
{
    L = new LNode;
    L->next = NULL;
    LNode *r = L;
    for (int i = 0; i < n; i++)
    {
        LNode *p = new LNode;
        cin >> p->data;
        p->next = NULL;
        r->next = p;
        r = p;
    }
}


//单链表内容的遍历
void ListDisply(Linklist L)
{
    printf("单链表中的内容为:");
    LNode *p;
    p = L->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n\n\n\n");
}



int main()
{
    //创建一个链表
    Linklist L;
    InitList(L);

    Linklist K;
    InitList(K);

    Linklist P;
    InitList(P);

    //创建三个结点
    LNode *a, *b, *c;
    a = new LNode;
    b = new LNode;
    c = new LNode;

    //判断空表
    if (!ListEmpty(L))
        printf("it is not empty!\n");
    else
        printf("it is empty!\n");

    //将三个结点串成串连成线儿
    L->next = a;
    a->next = b;
    b->next = c;
    c->next = NULL;


    if (!ListEmpty(L))
        printf("it is not empty!\n");
    else
        printf("it is empty!\n");

    //给三个结点的数据域赋值
    a->data = 23;
    b->data = 87;
    c->data = 99;

    printf("the length of list is: %d\n", ListLength(L));

    //获取第i个元素的值
    int e;
    GetElem(L, 2, e);
    printf("the value of second is:%d\n", e);

    //单链表的查找---返回地址
    printf("\n\nLocateElem--23:  %x\n", (unsigned)LocateElem(L, 23));
    printf("LocateElem--87:  %x\n", (unsigned)LocateElem(L, 87));
    printf("LocateElem--99:  %x\n", (unsigned)LocateElem(L, 99));
    //单链表的查找---返回序号
    printf("LocateElemInt--87:  %d\n\n\n", LocateElemInt(L, 23));

    //头插法建立单链表---输入几个元素
    cout << "头插法建立单链表,请输入数据:" << endl;
    CreatList_H(K, 5);
    printf("the length of list is: %d\n", ListLength(K));
    //单链表的遍历
    ListDisply(K);

    //尾插法建立单链表---输入几个元素
    cout << "尾插法建立单链表,请输入数据:" << endl;
    CreatList_R(P,5);
    printf("the length of list is: %d\n\n", ListLength(P));
    //单链表的遍历
    ListDisply(P);


    getchar();
    getchar();
    getchar();
    return 0;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM