顺序表的实现

来源:互联网 发布:沙耶之歌 知乎 编辑:程序博客网 时间:2024/05/23 22:18

                                                    顺序表的实现   

             顺序表是在计算机内存中以数组形式保存的线性表,是指用一组地址连续的储存单元依次存储数据元素的线性结构。线性表采用顺序储存的储存方式就称之为顺序表。

        今天,我们用C++来实现一种简单的顺序表

首先,建立顺序表的结构模型:

给出 Seqlist.h 文件来构造顺序表的框架和一些函数功能的实现

#ifndef _SEQLIST_H_

#define _SEQLIST_H_          这是C和C++定义头文件的一个技巧,作用是:  如果程序没有定义Seqlist.h文件,则定义                                       文件, 这样做的好处是,有效的防止了同一个头文件重复定义。当然 别忘了最                                                               后#endif

#include<iostream>

#include<malloc.h>

using namespace std;


template<typename Type>     //我们用模板来定义类型,使得各个数据类型都可以实现

class SeqList                            class  定义出 SeqList 这个类

{

public:                                                 

    SeqList(int sz = DEFAULT_SIZE);         //构造的函数,其中sz 是顺序表的 容量

    ~SeqList();                                             //析构函数 ,其实不用声明也默认存在

public:

    bool IsFull()const                                    //  顺序表的判空 判满,这些 都是我们构造顺序表所必须的

    {return size>=capacity;}

    bool IsEmpty()const

    {return size == 0;}


private:                                                        //然后我们在私有成员里定义出顺序表的数据。

    enum{DEFAULT_SIZE=8};                      // 使用枚举类型全局有效

    Type *base;                                              这是我们定义的 Type 类型的指针

    int capacity;                                                

    int size; 以及顺序表所实现的数组元素数量标记,这方便对数组进行操作

};



                                                     我们在定义一些函数操作

public:

    void push_back(const Type &x);                        尾插

    void push_fornt(const Type &x); 头插

    void show_seqlist()const; 顺序表的显示

    void sort_seqlist();   顺序表的排序

    void pop_back();  头删

    void pop_fornt();  尾 删

    void insert_pos(const Type &x, const int &pos);      按 位置插入

    void insert_value(const Type &x);                             按数据插入

    void delete_pos(int &pos);                                        按位置删除

    void delete_value(const Type &x); 按数值删除

    Type find_pos(const int &pos); 按位置查值

    int *find_value(const Type &x, int &num); 按数据查值

    int length_seqlist(); 长度

    void clear();

    void resver(); 逆序

    void remove_all(const Type &x);                                删除所有相同的要求数

};


下面给出我所写的这些函数的实现方法。

 

首先在实现函数时,别忘了我们模板的定义, template 是模板的关键字 调用时可以使用任意类型的 Type.

template<typename Type>

SeqList<Type>::SeqList(int sz)   在public 外实现函数,我们要加上函数 :: 所在域。

{

    capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;           

    base = new Type[capacity];

    size = 0;

}

template<typename Type>

SeqList<Type>::~SeqList()

{

    delete []base;

    base = NULL;

    capacity = size = 0;

}

template<typename Type>

void SeqList<Type>::push_back(const Type &x) 尾插法很简单,将数据写入base 再将size++  就可以啦

{

    if(!IsFull())

    {

        base[size++] = x;

    }else{

cout<<"sorry,is full!"<<endl<<"the biggest size: "<< size <<endl;

    }

}

 

template<typename Type>

void SeqList<Type>::push_fornt(const Type &x)          头插法比尾插法复杂一点,关键在于将数据插入头部时不能覆

{   盖原始数据,否则会使原始数据丢失,所以要将数据往后移

    if(!IsFull())                                                                      从最后一个数据开始移动,直到 base[0]。 在将base[0]=x,写入

    {

        for(int i = size; i >= 0; --i){

    base[i] = base[i-1];

}

base[0] = x;

++size;

    }else{

cout<<"sorry,is full!"<<endl<<"the biggest size: "<< size <<endl;

    }

}

 

 

template<typename Type>

void SeqList<Type>::insert_pos(const Type &x,const int &pos)

{    

    if(!IsFull())

    {

        if(pos > 0 && pos <= size+1){ 先找出位置,在相当于头插法插入

    if(pos == size+1){

                ++size;

base[size-1] = x;

    }else{

            for(int i = size; i >= pos; --i){

        base[i] = base[i-1];

    }

        base[pos-1] = x;

        ++size;

            }

        }else

    cout<<"wrong pos!"<<endl<<"Please insert 1 ~"<< size+1 <<endl;

    }else{

    cout<<"sorry,is full!"<<endl<<"the biggest size: "<< size <<endl;

      

    }

 

}

template<typename Type>

void SeqList<Type>::insert_value(const Type &x) 按值插入,我们就不得不先进行排序,调用后面的排序 函数。

{

   if(!IsFull()){

        sort_seqlist();

int i;

int temp = 0;

        base[size] = x;

        for(i = size-1; i >= 0 && base[i] > base[i+1]; --i){

    temp = base[i+1];

    base[i+1] = base[i];

    base[i] = temp;

}   

++size;   

    }else{

        cout<<"sorry,is full!"<<endl<<"the biggest size: "<< size <<endl;      

    }

}

 

template<typename Type>

void SeqList<Type>::pop_back()

{  

    if(size != 0){

        cout<<base[size-1]<<"已删除!"<<endl;

        --size;

    }else

    cout<<"sorry,no num!"<<endl;

}

 

template<typename Type> 这些简单的就不用多讲了

void SeqList<Type>::pop_fornt()

{  

    if(size != 0){

cout<<base[0]<<"已删除!"<<endl;

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

            base[i] = base[i+1];

        }

--size;            

    }else

    cout<<"sorry,no num!"<<endl;

}

 

template<typename Type>

void SeqList<Type>::delete_pos(int &pos)

{  

    if(size != 0){

        if(pos > 0 && pos <= size){  

    cout<<base[pos-1]<<"已删除!"<<endl;

            for(int i = pos-1; i < size; ++i){ 编写函数时一定要注意程序的鲁棒性,及程序调用的各种情况都要

             base[i] = base[i+1];  考虑,不能让程序 “无方法可选" ,比如按位置删除的函数,我们必

        } 需对位置的范围进行限制。

    --size;

        }else{

   cout << "please inseart " <<" 1 ~ "<< size << endl;

}          

    }else

        cout<<"sorry,no num!"<<endl;

}

 

template<typename Type>

void SeqList<Type>::delete_value(const Type &x)

{  

    sort_seqlist();

    int i;

    for(i = 0; i < size; ++i){

        if(base[i] == x)

break;

    }

    if(i != size){

for(int j = i+1; j < size; ++j){

    base[j-1] = base[j];

}

--size;

    }else

        cout<<"sorry,no this num!"<<endl;

}

 

template<typename Type>

void SeqList<Type>::remove_all(const Type &x)   在编写程序时另一点要注意的就是尽量“偷懒“,即就是函数的重用

{ 行,在这个函数中,我们要删除所有相同的数

    if(size != 0){ 比如 1 3 2 4 2 3 8 14                         如果要删除2 就要把所有2都删除。

        int num =  0; 首先 要先找出2的位置, 很巧我们在上面实现的这个功能

        int pos = -1; find_pos                                         函数,所以调用,找出2的所有位置。

int *p = find_value(x, num); 然后按位置删除,很巧 ,我们在上面同样实现了这个函数

if(p != NULL){ delete_pos,                                   我们在进行调用。

            for(int i = 0; i < num; i++){                            如果直接调用,程序结果是错误的,为什么呢?

pos = p[i] - i; —————————————————— 注意关键 在这里,当我们删掉第一个位置的2后,其他的位

delete_pos(pos);                                                      置其实都向前移动了一个位置,删除依次,向前移动依次,所以原

    } 本的位置不可用,我们要进行调整。即就是p[i] - i;

}else{

            cout << "sorry, wrong num!"<<endl;

}

    }else{

cout << "sorry, no num!" << endl;

    }

}

 

template<typename Type>

void SeqList<Type>::show_seqlist()const

{

    for(int i=0; i<size; ++i)

    {

        cout<<base[i]<<" ";

    }

     cout<<endl;

}

 

template<typename Type>

Type SeqList<Type>::find_pos(const int &pos)

{

    if(size != 0){

        if(pos > 0 && pos <= size){  

    cout << "" << pos << "个数是: " << base[pos-1] << endl;

    return base[pos-1];   

        }else{

            cout << "please inseart " <<" 1 ~ "<< size << endl;

        }          

    }else

        cout<<"sorry,no num!"<<endl;

}

 

template<typename Type>

int *SeqList<Type>::find_value(const Type &x, int &num)

{

    bool j = false;

    int *pos_array = (int *)malloc(sizeof(int) * size);

    if(size != 0){

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

    if(base[i] == x){

cout << i+1 << ",";

j = true;

pos_array[num] = i + 1;                               //将所有查找到的位置记录于数组并返回

++num;

    }

}

if(j == true){

    cout << "" << x << "所在的位置" << endl;

    return pos_array;

        }else

    cout << "没有找到" << x <<endl;

    }else

cout << "sorry, no num!" << endl;

    return NULL;

}

 

 

 

template<typename Type>                                             在这里排序我们用了选择排序法,关于排序的详细解释,

void SeqList<Type>::sort_seqlist() 会在以后给出。

{

    if(size != 0){

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

    for(int j = i-1; j >= 0 && base[j] > base[j+1]; --j){

        int temp = base[j+1];

        base[j+1] = base[j];

        base[j] = temp;        

            }

        }

    }else{

cout << "sorry, no num!";

    }

}

 

 

 

template<typename Type>

void SeqList<Type>::resver()            逆序时,用两个指针是个很棒的想法,无疑简化了程序

{

    int i = 0;

    int j = size-1;

    int temp = 0;

    if(size != 0){

while(i < j){

    temp = base[i];

    base[i] = base[j];

         base[j] = temp;

    i++;

            j--;

        }

    }else{

cout << "no num!" << endl;

    }

}

 

template<typename Type>

void SeqList<Type>::clear()

{

    size = 0;

    cout << "done!"<<endl;

}

 

template<typename Type>

int SeqList<Type>::length_seqlist()

{

    cout << "长度为: " << size << endl;

    return size;

}

 

#endif

这样我们就完成了Seqlist.h 的代码部分,就下来就是main()函数的实现了

上代码

#include<iostream>
#include"test.h"
using namespace std;

int main()
{
    SeqList<int> mylist;     在这里就是模板的类型选择了,我们用int 做个示范
    int select = 1;
    int pos = -1;
    int Item = -1;
    int num = 0;
    while(select)
    {
        cout<<"*****************************************************"<<endl;
        cout<<"* [1] push_back(-1结束)    [2] push_fornt(-1结束)   *"<<endl;
        cout<<"* [3] show_seqlist         [0] quit system          *"<<endl;
        cout<<"* [4] pop_back             [5] pop_fornt            *"<<endl;
        cout<<"* [6] insert_pos           [7] insert_value         *"<<endl;
        cout<<"* [8] delete_pos           [9] delete_value         *"<<endl;
        cout<<"* [10] find_pos            [11] find_value          *"<<endl;
        cout<<"* [12] sort               [13] resver              *"<<endl;
        cout<<"* [14] clear               [15] length              *"<<endl;
        cout<<"* [16] remove_all         &[17] destroy             *"<<endl;
        cout<<"*****************************************************"<<endl;
        cout<<"请选择:>";
        cin>>select;
        switch(select)
        {
case 0:
    return 0;        主函数这块没什么用讲的, 注意一点 是mylist类下的函
         case 1: 数,所以用mylist.的方式调用。
             cout<<"请输入要插入的数据(以-1结束)//尾插:";
             while(cin>>Item, Item != -1)
             {
                 mylist.push_back(Item);
             }
             break;  
         case 2:
             cout<<"请输入要插入的数据(以-1结束)//头插:";
             while(cin>>Item, Item != -1)
             {
                 mylist.push_fornt(Item);
             }
             break;
         case 3:
             mylist.show_seqlist();
             break;
case 4:
    mylist.pop_back();
    mylist.show_seqlist();
    break;
case 5:
    mylist.pop_fornt();
    mylist.show_seqlist();
    break;
         case 6:
             cout<<"请输入要插入的数据,和位置(-1 0结束):"<<endl;
             while(cin>>Item, Item != -1)
             {   
      cin>>pos;
                 mylist.insert_pos(Item, pos);
        mylist.show_seqlist();
             }
             break;  
        case 7:
             cout<<"请输入要插入的数据(-1 结束):"<<endl;
             while(cin>>Item, Item != -1)
             {
                 mylist.insert_value(Item);
        mylist.show_seqlist();
             }
             break;       
         case 8:
    cout << "请输入要删除的位置(-1结束)"<< endl;
    while(cin >> pos, pos != -1){
        mylist.delete_pos(pos); 
        mylist.show_seqlist();
    }
    break;
case 9:
             cout<<"请输入要删除的数据(-1 结束):"<<endl;
             while(cin>>Item, Item != -1)
             {
                 mylist.delete_value(Item);
        mylist.show_seqlist();
             }
             break;
case 10:
    cout << "请输入要查找的位置 (-1结束):" << endl;
    while(cin >> pos, pos != -1){
mylist.find_pos(pos);
mylist.show_seqlist();
    }  
    break;
case 11:
    cout << "请输入要查找的数据 (-1结束)" << endl;
    while(cin >> Item, Item != -1){
        mylist.find_value(Item, num);
mylist.show_seqlist();
    }
    break;
         case 12:
    mylist.sort_seqlist();
        mylist.show_seqlist();
    break;
case 13:
    mylist.resver();
    mylist.show_seqlist();
    break;
case 14:
    mylist.clear();
    break;
case 15:
    mylist.length_seqlist();
    break;
case 16:
    cout << "请输入要删除的数据 (-1结束)" << endl;
    while(cin >> Item, Item != -1){
        mylist.remove_all(Item);
mylist.show_seqlist();
    }
    break;
        }     
    }     
    return 0;
}


这样我们就完成了整个顺序表代码的实现,看看运行结果吧!



我们顺序表的实现的成功的。

     第一次写博客,水平有限,但只要写博客能持之以恒,能力一定能够提高。加油!

                                                                                                                                                  染尘    4.9



2 0