数据结构(二):线性表的链式存储结构-单链表的实现

单链表节点类型

在单链表中,一个节点的结构包含:数据域和指针域

template <typename T>//定义模板节点类型
struct LinkList
{
    T data;//存放数据元素
    LinkList<T> *next;//用于指向下一个节点的指针域
 };

基本运算算法

template <class T>
 class LinkListClass{
    LinkList<T> *head;              //单链表头节点 
public:
    LinkListClass<T>();             //构造函数,创建一个空单链表 
    ~LinkListClass<T>();           //析构函数 
    void CreateListF(T a[], int n);//头插法建表 
    void CreateListR(T a[], int n);//尾插法建表 
    void DispList();                //遍历显示链表数据 
    int ListLength();               //求长度 
    bool GetElem(int i, T &e);      //求链表中某个数据元素的值 
    int LocateElem(T e);            //按元素值查找 
    bool ListInsert(int i , T e);   //插入数据元素 
    bool ListDelete(int i);         //删除元素 


public: //友元函数  开放型
    //查找最后一个值为X的节点逻辑序号
    template<typename C>
    friend int Findlast(LinkListClass<C> &L, C x); 

    //逆置链表中所有的节点
    template<typename D>
    friend void Reverse(LinkListClass<D> &L); 

    //两个链表交叉存放到第三个链表中
    template<typename A>
    friend void Combo(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3); 

    //二路归并 
    template<typename A>
    friend void Merge2(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3);

 };

C++中模板类使用友元模板函数 – – 开放型

指的是友元函数声明在模板类中, 但是在类外进行定义

 template <class T>
 class LinkListClass{
public:
    //查找最后一个值为X的节点逻辑序号
    template<typename C>
    friend int Findlast(LinkListClass<C> &L, C x);
};

template<typename C>
int Findlast(LinkListClass<C> &L, C x)
{
    …………
}

注意点: 友元函数需声明为 public:

实现代码

#include<iostream>
using namespace std;


template <typename T>
struct LinkList
{
    T data;
    LinkList<T> *next;
 };

 template <class T>
 class LinkListClass{
    LinkList<T> *head;              //单链表头节点 
public:
    LinkListClass<T>();             //构造函数,创建一个空单链表 
    ~LinkListClass<T>();           //析构函数 
    void CreateListF(T a[], int n);//头插法建表 
    void CreateListR(T a[], int n);//尾插法建表 
    void DispList();                //遍历显示链表数据 
    int ListLength();               //求长度 
    bool GetElem(int i, T &e);      //求链表中某个数据元素的值 
    int LocateElem(T e);            //按元素值查找 
    bool ListInsert(int i , T e);   //插入数据元素 
    bool ListDelete(int i);         //删除元素 


public:     //友元函数 
    //查找最后一个值为X的节点逻辑序号
    template<typename C>
    friend int Findlast(LinkListClass<C> &L, C x); 

    //逆置链表中所有的节点
    template<typename D>
    friend void Reverse(LinkListClass<D> &L); 

    //两个链表交叉存放到第三个链表中
    template<typename A>
    friend void Combo(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3); 

    //二路归并 
    template<typename A>
    friend void Merge2(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3);

 };


 template<typename C>
int Findlast(LinkListClass<C> &L, C x)
{
    LinkList<C> *p = L.head->next;
    int i = 0, j = i;
    while(p != NULL)
    {
        i ++;
        if(p->data == x) j = i;
        p = p->next;
    }
    return j;
}

template<typename D>
void Reverse(LinkListClass<D> &L)
{
    LinkList<D> *p = L.head->next, *q;
    L.head->next = NULL;
    while(p != NULL)
    {
        q = p->next;
        p->next = L.head->next;
        L.head->next = p;
        p = q;
    }
}


//两个链表交叉存放到第三个链表中
template<typename A>
void Combo(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3) 
{
    LinkList<A> *p = L1.head->next, *q = L2.head->next;
    LinkList<A> *s, *r;
    r = L3.head;

    while(p != NULL && q != NULL)
    {
        s = new LinkList<A>();
        s->data = p->data;
        r->next = s;
        r = s;
        p = p->next;

        s = new LinkList<A>();
        s->data = q->data;
        r->next = s;
        r = s;
        q = q->next; 
    }

    while(p != NULL)
    {
        s = new LinkList<A>();
        s->data = p->data;
        r->next = s;
        r = s;
        p = p->next;
    }

        while(q != NULL)
    {
        s = new LinkList<A>();
        s->data = q->data;
        r->next = s;
        r = s;
        q = q->next;
    }

    r->next = NULL;
}

//二路归并 
template<typename A>
void Merge2(LinkListClass<A> &L1,LinkListClass<A> &L2, LinkListClass<A> &L3)
{
    LinkList<A> *p = L1.head->next, *q = L2.head->next;
    LinkList<A> *p1, *q1, *r;
    L1.head->next = NULL;
    L2.head->next = NULL;
    r = L3.head;

    while(p != NULL && q != NULL)
    {
        if(p->data < q->data)
        {
            p1 = p->next;
            r->next = p;
            r = p;
            p = p1;
        }
        else
        {
            q1 = q->next;
            r->next = q;
            r = q;
            q = q1;
        }
    }
    while(p != NULL)
    {
        p1= p->next;
        r->next = p;
        r = p;
        p = p1;
    }
    while(q != NULL)
    {
        q1= q->next;
        r->next = q;
        r = q;
        q = q1;
    }

}


 //初始化和销毁
 template<typename T>
 LinkListClass<T>::LinkListClass()
 {
    head = new LinkList<T>();
    head->next = NULL;
  } 
   template<typename T>
 LinkListClass<T>::~LinkListClass()
 {
    LinkList<T> *pre, *p;
    pre = head;
    p = pre->next;
    while(p != NULL)
    {
        delete pre;
        pre = p;
        p = p->next;
     }
     delete pre;
 }

 //建立单链表
 //头插法建表
 template<typename T>
 void LinkListClass<T>::CreateListF(T a[], int n)
 {
    LinkList<T> *s; int i;
    head->next = NULL;
    for(i = 0; i < n; i++)
    {
        s = new LinkList<T>();
        s->data = a[i];
        s->next = head->next;
        head->next = s;
     }
  } 
  //尾插法建表
template<typename T>
void LinkListClass<T>:: CreateListR(T a[], int n)
{
    LinkList<T> *s, *r;
    int i;
    r = head;
    for(i = 0; i < n; i++)
    {
        s = new LinkList<T>();
        s->data = a[i];
        r->next = s;
        r = s;
      }
      r->next = NULL;
} 


 //输出单链表
 template <typename T>
 void LinkListClass<T>::DispList()
 {
    LinkList<T> *p;
    p = head->next;
    while(p != NULL)
    {
        cout <<p->data<< " ";
         p = p->next; 
     }

     cout << endl;
  } 

 //求;链表长度
 template<typename T>
 int LinkListClass<T>::ListLength()
 {
    int i = 0;
    LinkList<T> *p;
    p = head;
    while(p->next != NULL)
    {
        i++;
        p = p.next;
     }
     return i;
  } 

  //求某个数据元素的值
  template<typename T>
  bool LinkListClass<T>::GetElem(int i, T &e)
  {
    int j = 0;
    LinkList<T> *p;
    p = head;
    while(j < i && p != NULL)
    {
        j++;
        p = p->next;
      }
      if(p == NULL)
        return false;
    else
    {
        e = p->data;
        return true;
    }
   } 

//按元素值查找
template<typename T>
int LinkListClass<T>::LocateElem(T e)
{
    int i = 1;
    LinkList<T> *p;
    while(p != NULL && p->data!=e)
    {
        p=p.next;
        i++;
    }
    if(p==NULL) return 0;
    else
    return i;
} 

 //插入数据元素
 template<typename T>
 bool LinkListClass<T>::ListInsert(int i, T e)
 {
    int j = 0;
    LinkList<T> *s, *p;
    if(i < 1) return false;
    p = head;
    while(j < i-1 && p != NULL)
    {
        j++;
        p = p.next;
     }
     if(p == NULL) return false;
     else
     {
        s = new LinkList<T>();
        s->data = e;
        s->next = p.next;
        p->next = s;
        return true;
     }
  } 

 //删除元素
 template<typename T>
 bool LinkListClass<T>::ListDelete(int i)
 {
    int j = 0;
    LinkList<T> *q, *p;
    if(i < 1) return false;
    p = head;
    while(j < i-1 && p != NULL)
    {
        j ++;
        p = p->next;
     }
     if(p == NULL) return false;
     else
     {
        q = p->next;
        if(q == NULL) return true;
        p->next = q->next;
        delete q;
        return true;
     }
  } 


 int main()
 {
    int n;
    int a[5] = {1,20,30,40,50};
    int a2[7] = {11,22,33,44,55,90,80};
    LinkListClass<int> Link;
    LinkListClass<int> Link2;
    LinkListClass<int> Link3;
    //Link.CreateListF(a, 5);
    Link.CreateListR(a, 5);
    Link2.CreateListR(a2, 7);
    //Link.GetElem(3, n);
    //cout << Findlast(Link, 2) << endl;
    //Reverse(Link);
    //Combo(Link, Link2, Link3);

    Link.DispList();
    cout << endl;
    Link2.DispList();
    cout << endl;

    Merge2(Link, Link2, Link3);

    //cout << n << endl;

    Link3.DispList();
    return 0;
 }

本人github链接: **https://github.com/ITMasterC** 欢迎来共同探讨,C++,cocos2dx游戏,数据结构,C语言实现小游戏代码…………

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值