链表
一、相关概念
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;
}