数据结构:链表1(单链表)

数据结构:单链表

单链表的定义:

   单链表是用一组任意的存储单元存放线性表的元素,这组存储单元可以连续也可以不连续,甚至可以零散分布在内存中的任意位置。每个存储单元在存储数据元素的同时,还必须存储其后记元素的地址信息,这个地址信息称为指针。这两部分组成了数据元素的存储映像,称为结点。结点node分为数据域data和指针域next。

(指针变量的三要素:名字、内存地址、值)

结点定义:(采用模板机制)

template <typename T>

struct Node

{

T data;

Node<T> *next;      //此处<T>也可以省略

};

头结点:如果链表有头节点,则链式结构中的第一个节点称为头结点:其数据域可以存储一些附加信息,如链表长度;其指针域指向链表中的第一个节点。

 

单链表的实现:

template <class T>

class LinkList {

public:

LinkList ( ) {first=new Node<T>; first -> next= NULL ;}

   LinkList ( T a[ ], int n ) ;

~LinkList ( ) ;

int Length ( ) ;

T Get ( int i ) ;

int Locate ( T x ) ;

void Insert ( int i, T x ) ;

T Delete ( int i ) ;

void PrintList ( ) ;

private:

Node<T>  *first; // 单链表的头指针  , <T>可以省略

};

 

构造函数:

头插法:

①带头结点

template <class T>  

LinkList<T>:: LinkList(T a[ ], int n) {

    first=new Node<T>;   //生成头结点

   first->next=NULL;

   Node<T> *s;

   for (int i=0; i<n; i++){

          s=new Node<T>;

          s->data=a[i];  //为每个数组元素建立一个结点

          s->next=first->next;

          first->next=s;

}

}

②不带头节点

{

    first=NULL;

    for(int i=0;i<n;i++)    {

         s=new node<T>;

         s->data=a[i];

         s->next=first;

         first=s;   

    }

}

 

尾插法:

①带头结点

template <class T>  

LinkList<T>:: LinkList(T a[ ], int n) {

    first=new Node<T>;   //生成头结点

   first->next=NULL;

   Node<T> *s;

   for (int i=0; i<n; i++){

          s=new Node<T>;

          s->data=a[i];  //为每个数组元素建立一个结点

          s->next=first->next;

          first->next=s;

}

}

②不带头结点

node<T> *r;

     head=NULL;

    if(n<=0)return;

    s=new node<T>;

    s->data=a[0];

    s->next=head;

    head=s;   

r=head;

for(int i=1;i<n;i++)    {

         s=new node<T>;

         s->data=a[i];

         r->next=s;

         r=s;   

    }

 

 

 

单链表的遍历:

template <class T>  

LinkList<T>:: PrintList()

{

    Node<T> *p;

p=first->next;          

     while(p)

{

cout<<p->data;

            p=p->next;

}

 }

 

查找算法:

①按位查找

1 工作指针P初始化,计数器初始化

2 执行下列操作,直到p为空或指向第i个节点

(1)工作指针后移

    (2) 计数器增1

3 若p为空,则第i个元素不存在,抛出位置异常;否则查找成功,返回节点p的数据元素

template <class T>

T LinkList<T>::Get(int i) {   

  Node<T> *p; int j;

  p=first->next;  j=1;  //或p=first;  j=0;

  while (p && j<i) {

     p=p->next;       //工作指针p后移

j++;

    }

  if (!p) throw "位置";

  else return p->data;

}

②按值查找

template<class T>

int LinkList<T>::Locate(T x){

  Node<T>*p=first->next; //工作指针初始化

  int count=1;//累加器count初始化

  while(p!=NULL)

  {

     if(p->data==x) return count;//查找成功返回序号

     p=p->next;

     count++;

  }

return 0;

}

 

插入算法:

1 工作指针p初始化,计数器初始化

2 查找第i-1个节点,并使工作指针p指向该节点

3 若查找不成功(P==NULL),说明位置错误,抛出位置异常,否则

(1)生成一个元素值为x的新节点s

(2)将s插入到p之后

①带头结点

template <class T>  

void LinkList<T>::Insert(int i, T x){  

   Node<T> *p; int j;

   p=first ; j=0;    //工作指针p初始化

   while (p && j<i-1)   {

     p=p->next;   //工作指针p后移

     j++;

   }

   if (!p) throw "位置";

    else {

  Node<T> *s;

      s=new Node<T>;

  s->data=x;  //向内存申请一个结点s,其数据域为x

      s->next=p->next;       //将结点s插入到结点p之后

      p->next=s;

}

 }

②不带头节点

Insert(int i, T x){  

   Node<T> *p; int j;

   if(i<=0) throw “位置非法”;

   if (i==1 ){ s=new Node<T>;s->next=head;head=s;return}

   p=first ; j=1;    //工作指针p初始化

   while (p && j<i-1)   {

     p=p->next;   //工作指针p后移

     j++;

   }

   if (!p) throw "位置";

    else {

  Node<T> *s;

      s=new Node<T>;

  s->data=x;  //向内存申请一个结点s,其数据域为x

      s->next=p->next;       //将结点s插入到结点p之后

      p->next=s;

}

 }

 

删除算法:

template <class T>  

T LinkList<T>::Delete(int i){

  Node<T> *p; int j;

  p=first ; j=0;  //工作指针p初始化

  while (p && j<i-1) {  //查找第i-1个结点

    p=p->next;

    j++;

  }

  if (!p || !p->next) throw "位置";  //结点p不存在或结点p的后继结点不存在

    else {

        Node<T> *q; T x;

          q=p->next; x=q->data;  //暂存被删结点

          p->next=q->next;  //摘链

          delete q;

          return x;

}

}

析构函数:含不含头节点都可

template <class T>

LinkList<T>:: ~LinkList()

{

   Node<T> *q;

   while (first)

   {

       q=first->next;

       delete first;

       first=q;

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值