链表

链表

一、相关概念

1、为什么要使用链表

先从顺序表的缺点说起,顺序表的插入和删除操作时我们需要移动大量的元素。有没有什么办法在执行这些操作的时候,不需要移动这么多的元素呢?链表应运而生。

2、链表

有若干个结点(元素)组成,每个结点除结点本身的信息外,增加了一个或多个指针字段来表示结点之间的关系。

常见的链表:单链表、双链表和循环链表

这个我们实现的是单链表

二、实现分析

1、基本属性

<1>结点的内容:data;
<2>结点的指针:next;

2、基本方法

(1)查找:
1.通过结点的位置来查找元素,返回元素地址;(这里我们找到的都是你想要操作的元素的前一个元素)
2.通过值来查找元素返回元素地址;

(2)插入
在第i个位置,插入一个值为item的元素;

1> 在链表为空时插入一个元素
2> 在链表表头插入一个元素
3> 在链表中插入一个元素

(3)删除
删除第i个位置的元素;
1> 删除第一个元素,也就是头结点
2> 删除第其他元素,将找到的元素的next指向你要删除的元素的next元素

(4)输出

“先进先出”的原则输出链表中的所有元素

(5)有序插入
将元素item按照一定的顺序存入链表

1> 第一步就是先判断一下head是否是空的;
1>> 如果是空的就将这个newNode添加成head;
2>> 如果不是空的,就进行下面的比较

2> 第二步就是开始比较大小;
1>> 如果比他大的话,while循环,看是否是最大,若是最大的话就将这个元素添加到最后面;newNode的next指向current,prePtr指向newNode;
2>> 如果比他小的话,就将这个newNode添加到prePtr的后面,将newNode的next指向current;

三、代码实现

//slist.cpp
#include <cstddef>
#include <iostream>
using namespace std;

template <class T>
struct Node
{
    T data;         //infomation od node;
    Node<T> *next;  //pointer filed indicating its successor;
    Node()          //constructor;
    {
        next = NULL;
    }
    Node(T item, Node<T> *add_on = NULL)
    {
        data = item;
        next = add_on;
    }
};

template <class T>
class slist
{
    private:
        Node<T>*head;

    public:
        slist();

        void find(int i, Node<T>* &p);

        T find(T key);

        void insert(int i, T item);

        void remove(int i);

        void print()const;

        void insert_order(T item);

        ~slist();              
};


//constructor:create am empty linked list.
template <class T>
slist<T>::slist()
{
    head = NULL; 
} 


//find i-th node and record its address as p.
template<class T>
void slist<T>::find(int i, Node<T>* &p)
{
    p = head;
    int j = 0; 
    while(p != NULL && (j < i-1))
    {
        p=p->next;
        j++;
    }   
}


//find the node whose value equals key and return it address;
template<class T>
T slist<T>::find(T key)
{
    Node<T> *p = head;
    while((p != NULL) && (p -> data != key))
        p = p -> next;
    return p->data;
}


//insert a node with value item after node i;
template<class T>
void slist<T>::insert(int i,T item)
{
    Node<T>*newnode=new Node<T>(item);
    if(i==0||(head==NULL))
    {
        newnode->next=head;
        head=newnode;
    }
    else
    {
        Node<T>*p=NULL;     
        find(i,p); 
        if(p!=NULL)
        {
            newnode->next = p->next;
            p->next=newnode;

        }
        if(p == NULL)
        {
            cout<<"error"<<endl;
        }

    }
}


//remove node i(i >= 1)from the link list;
template<class T>
void slist<T>::remove(int i)
{
    Node<T>*p, *q;
    if(i == 1)
    {
        p = head;
        head = head -> next;
    }
    else
    {
        find(i-1, q);
        p = q -> next;
        q ->next = p ->next;
    }   
    delete p;
} 


//output the single-linked list;
template<class T>
void slist<T>::print()const
{
    Node<T> *p = head;
    while(p != NULL)
    {
        cout<<p->data<<"  ";
        p = p -> next;
    }
}


//create an rderedly single-linked list;
template<class T>
void slist<T>::insert_order(T item)
{
    Node<T> *currPtr, *prePtr, *newNode;
    newNode = new Node<T>(item, NULL);
    prePtr = NULL;
    currPtr = head;
    while(currPtr != NULL)
    {
        if(item < currPtr -> data)
        {
            break;
        }
        prePtr = currPtr;
        currPtr = currPtr -> next;
    }
    if(prePtr == NULL)  //如果头是空的话,就将newNode设置为head;
    {
        newNode -> next = head;
        head = newNode;
    }
    else                //如果这个newNode是最大的让就会被添加到最后一个位置;
    {                   //如果这个数比较小的话,也会采用下面的这两段代码;
        newNode -> next = currPtr; //(NULL)
        prePtr -> next = newNode;
    }
}


//destructor--leaving the linked list empty;
template<class T>
slist<T>::~slist()
{
    Node<T> *currPtr, *nextPtr;
    currPtr = head;
    while(currPtr != NULL)
    {
        nextPtr == currPtr -> next;
        delete currPtr;
        currPtr = nextPtr;
    } 
    head = NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值