單鏈表類的定義與實現


/////////////////////////////////////////////////////////////////
//日期:2014-11-03
//作者:Davis
//功能:單鏈表的定義與操作實現
/////////////////////////////////////////////////////////////////
#pragma once
template<class T>
struct Node
{
    T data;     //數據域,存放表元素
    Node *next; //指針域。指向下一個結點
};

template<class T>
class linkList
{
private:

    Node<T> *Head; //鏈表頭指針

public:
    //構造函數、創建空鏈表
    linkList(void)
    {
      Head = new Node<T>;
      Head->next = NULL;
    }

    //析構函數、刪除空鏈表
    ~linkList(void)
    {
      Node<T> *p;
      while(Head)
      {
        p = Head;//從頭節點開始,依次釋放結點
        Head = Head->next;
        delete p;
      }
      Head = NULL;//頭結點指向空
    }

    //創建具有n個元素的線性鏈表
    void createList(int n)
    {                 //尾插法(正序)創建具有n個元素的線性表
      Node<T> *p,*s;  //設置工作指針,p指向尾結點
      p=Head;
      cout<<"請依次輸入"<<n<<"個元素值"<<endl;
      for(int i=1;i<=n;i++)
      {
        s = new Node<T>;   //新建元素結點
        cin>>s->data;      //輸入新建數據元素值
        s->next = p->next; //新結點鏈入表尾
        p->next = s;
        p = s;             //p是工作指針
      }
    }

    //在表中第i個位置插入元素
    void Insert(int i,T e)
    {
      int j = 0;
      Node<T> *p;
      p = Head;         //工作指針p指向頭結點
      while(p && j<i-1) //查找第i-1個結點
      {
        p = p->next;
        j++;
      }
      if(!p || j>i-1)throw"位置異常";
      else
      {
        Node<T> *s;
        s = new Node<T>;  //創建新節點
        s->data = e;
        s->next = p->next;//結點s鏈到p結點之后
        p->next = s;
      }
    }

    T Delete(int i)//刪除表中第i個元素
    {
          T x;
        Node<T> *p,*q;
        p = Head;  //從頭結點開始查找
        int j = 0; //計數器初始化
        while(p->next && j<i-1)//p定位到刪除結點的前驅
        {
          p = p->next;
          j++;
        }
        if(!p->next || j>i-1)throw"位置異常";//刪除位置不合理
        else                                 //刪除位置合理
        {
          q = p->next;      //暫存刪除結點位置
          p->next = q->next;//從鏈表中摘除刪除結點
          x = q->data;      //取刪除數據元素的值
          delete q;         //釋放刪除點
          return x;         //返回刪除元素的值
        }
     }

    //獲取第i個元素的值
    T getElem(int i)
    {
      Node<T> *p;     //設置工作指針
      p = Head->next; //從首結點開始
      int j = 1;      //計數器初始化
      while(p && j<i) //定位到第i個元素結點
      {
          p = p->next;
          j++;
      }
      if(!p || j>i)
      {
          throw "位置異常";
      }
      else   //位置合理
      {
        return p->data;
      }
    }

    //在鏈表中查找值為e的元素
    int Locate(T e)
    {
      int j = 1;
      Node<T> *p;
      p = Head->next;
      while(p && p->data != e)
      {
        p = p->next;
        j++;
      }
      if(!p )//未找到,范圍0
      {
          return 0;
      }
      else  //找到,返回位序
      {
          return j;
      }
    }

    //返回元素e的前驅
    T prior(T e)
    {
      Node<T> *p,*q;
      p = Head;
      q = p->next;
      while(q && q->data != e)
      {
        p = q;
        q = q->next;
      }
      if(p == Head)
      {
        throw "首元素,無前驅";
      }
      else if(!q)
      {
        throw "元素不存在";
      }
      else
      {
        return p->data;
      }
    }
    
    //測表空
    int Empty()
    {
      if(Head->next == NULL)
          return 1; //空表返回1
      else
          return 0; //非空表,返回0
    }

    //測表長
    int Length()
    {
      int len = 0; //計數器初始化
      Node<T> *p;  //設置頭指針
      p=Head;      //指向頭指針
      while(p->next)
      {
        len++;
        p = p->next;
      }
      return len;  //返回表長
    }

    //輸出表元素
    void listDisplay()
    {
      Node<T> *p;
      p = Head->next;
      int i = 1;
      while(p)
      {
        cout<<i<<"\t";
        cout<<p->data<<endl;
        p = p->next;
        i++;
      }
    }
};

/////////////////////////////////////////////////////////////////
//功能:單鏈表類的測試
//////////////////////////////////////////////////////////////////
// linkList_Test.cpp : 定義控制台應用程序的入口點。
#include "stdafx.h"
#include "linkList.h"
#include "process.h"//exit()
#include<iostream>

using namespace std;
char pause;
typedef int T;

int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    T e,prior_e;
    linkList<int>L;   //建立整形空鏈表
    system("cls");    //執行系統命令,清屏
    int choice;
    do
    {
      cout<<"1-創建鏈表\n";
      cout<<"2-在鏈表第i個位置插入元素\n";
      cout<<"3-刪除鏈表中第i個位置的元素\n";
      cout<<"4-返回第i個元素的值\n";
      cout<<"5-元素定位\n";
      cout<<"6-按值求前驅\n";
      cout<<"7-測表空\n";
      cout<<"8-測表長\n";
      cout<<"9-顯示鏈表\n";
      cout<<"10-退出\n";
      cout<<"Enter choice:";
      cin>>choice;
      switch(choice)
      {
      case 1://創建鏈表
             cout<<"請輸入要創建的鏈表中元素的個數:";
             cin>>i;
             cout<<endl;
             L.createList(i);         
             break;
      case 2://元素插入
           cout<<"請輸入插入的位置";
           cin>>i;
           cout<<endl;
           cout<<"請輸入插入元素的值:";
           cin>>e;
           cout<<endl;
           try
           {
               L.Insert(i,e);
           }
           catch(char* err)
           {
             cout<<err<<endl;
           }
           break;
      case 3://元素刪除
          cout<<"請輸入刪除位置";
          cin>>i;
          cout<<endl;
          try
          {
              e = L.Delete(i);
              cout<<"被刪除元素為:"<<e<<endl;
          }
          catch(char* err)
          {
             cout<<err<<endl;
          }
          cin.get(pause);
          system("pause");
          break;
      case 4://返回第i個元素值
          cout<<"請輸入要查詢的元素位置:";
          cin>>i;
          try
          {
              e = L.getElem(i);
              cout<<""<<i<<"個元素值為:"<<e<<endl;
          }
          catch(char* err)
          {
            cout<<err<<endl;
          }
          cin.get(pause);
          system("pause");
          break;
      case 5://按值進行元素查詢
          cout<<"請輸入要查詢的元素值:";
          cin>>e;
          i = L.Locate(e);
          cout<<"查詢元素"<<e<<"在鏈表中的位置為:"<<i<<endl;
          cin.get(pause);
          system("pause");
          break;
      case  6://求元素前驅
          cout<<"請輸入要求前驅元素的值:";
          cin>>e;
          try
          {
              prior_e = L.prior(e);
              cout<<"元素"<<e<<"的前驅值為:"<<prior_e<<endl;
          }
          catch(char *err)
          {
            cout<<err<<endl;
          }
          cin.get(pause);
          system("pause");
          break;
      case 7://測表空
          i = L.Empty();
          if(i)
          {
            cout<<"表空"<<endl;
          }
          else
          {
            cout<<"表不空"<<endl;
          }
          cin.get(pause);
          system("pause");
          break;
      case 8://測表長
          cout<<"鏈表長度為:"<<L.Length()<<endl;
          cin.get(pause);
          system("pause");
          break;
      case 9://遍歷輸出表
          L.listDisplay();
          cout<<endl;
          cin.get(pause);
          system("pause");
          break;
      case 10://退出
          break;
      default://非法選擇
          cout<<"Invalid choice";
          break;
      }       

    }while(choice != 10);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM