线性表的链式存储结构——单链表(头插法)

线性表的顺序存储结构最大的缺点在于:每次需要插入或者删除元素时,需要移动大量的元素,增加算法的时间复杂度。

链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素,这些存储单元可以是连续的,也可以是不连续的。单链表是由n个链结成的一个链表,即为线性表的链式存储结构,链表中的每个结点只包含一个指针域。
头指针:链表中第一个结点的存储位置叫做头指针。头指针是指向链表第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识的作用,所以常用头指针来作为链表的名字,无论链表是否为空,头指针均不能为空,头指针是链表中的必要元素。
创建一个单链表:
1.声明单链表的数据结构

struct Node{
    int data;
    Node *next;
} *LinkList;

2.创建一个单链表,并返回链表的头指针

Node *CreateLinkList(int n){
    //声明一个头指针,作为函数返回值,表示当前创建的链表
    Node *head;
    Node *p;
    //初始化链表的头结点
    LinkList=new Node;
    //初始化头指针
    head=LinkList;
    LinkList->next=NULL;
    //向链表中填充数据
    for(auto i=0;i<n;i++){
    	p = new Node;
        p->data=i;
        p->next=LinkList->next;
        LinkList->next=p;
    }
    return head;
}

3.循环遍历单链表中的数据元素

//head代表需要遍历的链表的头指针
void ForeachLinkList(Node *head){
    Node *p=head->next;
    while(p!=NULL){
        cout<<p->data<<endl;
        p=p->next;
    }
}

4.输出链表中的元素

int main(){
    Node *head=CreateLinkList(10);
    ForeachLinkList(head);
    return 0;
}

5.取得指定位置的元素

//head代表要查找链表的头指针
//n代表要查找元素的位置
int GetElement(Node *head,int n){
    int j=1;
    Node *p=head->next;
    while(p!=NULL&&j<n){
        p=p->next;
        j++;
    }
    return (p->data);
}

从单链表中插入和删除数据过程

<插入>从单链表的第n个位置中插入数据算法思路

1.声明指针p指向链表的头结点,声明并初始化j从1开始。

2.当j小于n时,遍历链表,移动指针p,指向下一个结点,j值累加

3.如果到链表末尾p指针为空,则要删除的结点不存在。

向链表中插入数据过程如下:

bool InsertElement(Node *head, int n, int element) {
    int j = 0;
    Node *p, *newNode;
    p = head;
    while (p != NULL && j < n) {
        p = p->next;
        j++;
    }
    if (p == NULL || j > n) {
        return false;
    }
    newNode = new Node;
    newNode->data = element;
    newNode->next = p->next; 
    p->next = newNode;
    return true;
}

<删除>从链表中第n个位置删除数据算法思路

1.声明一个指针p指向链表的头结点,初始化j的值从1开始

2.当j小于n时,遍历链表,后移指针p,使其指向链表的下一个结点,j的值累加1;

3.如果p的值为空,说明要删除的结点不存在;

向链表中删除数据过程如下:

//从链表中删除数据
bool DeleteElement(Node *head, int n) {
    int j = 0;
    Node *p, *deleteNode;
    p = head;
    while (p&&j < n) {
        p = p->next;
        j++;
    }
    if (p == NULL || j > n) {
        return false;
    }
    deleteNode = p->next;
    p->next = deleteNode->next;
    delete deleteNode;
    return true;
}

主函数中测试代码如下:

int main()
{
    Node *head = CreateLinkList(10);
    cout << "-----分割线-------" << endl;
    cout << "初始链表中的数据元素" << endl;
    ForeachLinkList(head);
    cout << "从单链表中获取第五个结点的数据值" << endl;
    cout << GetElementFromLinkList(head, 7) << endl;
    cout << "-----分割线-------" << endl;
    InsertElement(head, 3, 88);
    cout << "向链表的第三个位置插入数据后,链表中的元素如下" << endl;
    ForeachLinkList(head);
    cout << "-----分割线-------" << endl;
    DeleteElement(head, 2);
    cout << "删除链表中第二个位置的数据后,链表中的元素如下" << endl;
    ForeachLinkList(head);
    return 0;
}

输出:

工程文件地址:https://github.com/USuperMe/SinglyLinkList.git

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值