您的位置:首页 > 其它

线性表链式存储(静态链表)及其12种操作的实现

2015-03-26 00:45 337 查看
该表格中的所有复杂度均指的是当前程序中算法的复杂度,同一个操作算法不同复杂度不同。

对于空间复杂度:没有程序的空间复杂度为0,任何程序的运行必须要空间。当所需的空间是常数的,就是O(1);是线性的,就是O(n),以此类推。

操作

时间复杂度(T(n))

空间复杂度(S(n))

判断是否为空

O(1)

O(1)

得到长度

O(n)

O(1)

转置线性表

O(n)

O(1)

得到指定下标的元素

O(n)

O(1)

得到指定元素的下标

O(n)

O(1)

插入元素

O(n)

O(1)

删除元素

O(n)

O(1)

冒泡排序

O(n^2)

O(1)

清空当前线性表

O(n)

O(1)

因为整个一维数组的空间早已经声明,只是使用和不使用之分,无开辟新内存和回收内存

归并两个已经有序的线性表(长度分别n,m)的交集到第一个线性表,且保持新表有序

O(n+m)

最坏的情况下

O(1)

事实上是多使用了O(m)的内存,因为要将s2的所有元素复制到s1中

/*  数据结构分析与学习专栏
*  Copyright (c) 2015, 山东大学计算机科学与技术专业学生
*  All rights reserved.
*   作    者:   高祥
*   完成日期:  2015 年 3 月 25 日
*   版 本 号:003
 
*任务描述:针对线性表的采用顺序存储结构,实现15个基本操作
*   1:建立静态链表,填充元素
*   2:输出静态链表
*   3:判断静态链表是否为空
*   4:求静态链表的长度
*   5:反转静态链表
*   6:查找静态链表指定下标的元素
*   7:求出给定元素在静态链表中第一次出现的位置
*   8:向静态链表中的指定位置插入元素
*   9:删除静态链表中指定位置的元素
*  10:清空当前静态链表
*  11:将静态链表按照升序排序
*  12:将两个静态链表归并到第一个静态链表中并按照升序排列
 
*主要函数:
*  1.void InitList(SLinkList &s);
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点
//0表示空指针
*  2.int Malloc(SLinkList &s);//若备用链表空间非空,则返回分配的结点下标,否则返回0
*  3.void Free(SLinkList &s,int index);//将下标为k的空闲节点回收到备用链表中
*  4.void FillList(SLinkList &s,int &head);
//填充静态链表的元素,注意:head要使用引用传值
*  5.void Output(SLinkList s,int head);//输出静态链表
*  6.Status IsEmpty(SLinkList s,int head);//判断静态链表是否为空
*  7.int ListLength(SLinkList s,int head);//求静态链表的长度
*  8.void ReverseList(SLinkList &s,int head);//反转静态链表
*  9.void GetElem(SLinkList s,int index,int head);//得到指定下标的元素
*  10.void GetIndex(SLinkList s,ElemType elem,int head);//得到指定元素的下标
*  11.void InsertList(SLinkList &s,int head,int index,ElemType elem);//插入元素
*  12.void DeleteList(SLinkList &s,int head,int index);//删除结点
*  13.Status ClearList(SLinkList &s,int head);//清空静态链表
*  14.void BubbleSort(SLinkList &s,int head);//冒泡排序
*  15.void MergeList(SLinkList &s1,int head1,SLinkList &s2,inthead2);
   //归并两个静态链表到第一个静态链表中并保持升序
*/
 
#include<iostream>
#include<algorithm>
using namespace std;
 
#define OK 1
#define FALSE 0
#define ERROR 0
#define MAXSIZE 100000
 
typedef int ElemType;
typedef int Status;
 
typedef struct
{
   ElemType data;
   int cur;
} component,SLinkList[MAXSIZE];
 
void Interaction();
 
void InitList(SLinkList &s);
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点,0表示空指针
 
int Malloc(SLinkList &s);//若备用链表空间非空,则返回分配的结点下标,否则返回0
 
void Free(SLinkList &s,int index);//将下标为k的空闲节点回收到备用链表中
 
void FillList(SLinkList &s,int&head);//填充静态链表的元素,注意:head要使用引用传值
 
void Output(SLinkList s,int head);//输出静态链表
 
Status IsEmpty(SLinkList s,int head);//判断静态链表是否为空
 
int ListLength(SLinkList s,int head);//求静态链表的长度
 
void ReverseList(SLinkList &s,inthead);//反转静态链表
 
void GetElem(SLinkList s,int index,inthead);//得到指定下标的元素
 
void GetIndex(SLinkList s,ElemType elem,inthead);//得到指定元素的下标
 
void InsertList(SLinkList &s,inthead,int index,ElemType elem);//插入元素
 
void DeleteList(SLinkList &s,inthead,int index);//删除结点
 
Status ClearList(SLinkList &s,inthead);//清空静态链表
 
void BubbleSort(SLinkList &s,inthead);//冒泡排序
 
void MergeList(SLinkList &s1,inthead1,SLinkList &s2,int head2);
//归并两个静态链表到第一个静态链表中并保持升序
 
int main()
{
   SLinkList s1,s2;
   Interaction();
   
   int operate;
   int head1,head2;
   while(cin>>operate)
    {
       switch(operate)
       {
       case 0:
           return 0;
           
       case 1:
           InitList(s1);
           FillList(s1,head1);
           break;
            
       case 2:
           Output(s1,head1);
           break;
           
       case 3:
           if(IsEmpty(s1,head1))
           {
                cout<<"静态链表为空。\n";
           }
           else
           {
                cout<<"静态链表不为空。\n";
           }
           break;
           
       case 4:
           cout<<"静态链表的长度是:"<<ListLength(s1,head1)<<endl;
           break;
           
       case 5:
           ReverseList(s1,head1);
           break;
           
       case 6:
           cout<<"请输入下标:";
           int index;
           cin>>index;
           GetElem(s1,index,head1);
           break;
           
       case 7:
           cout<<"请输入元素大小:";
           ElemType elem;
           cin>>elem;
           GetIndex(s1,elem,head1);
           break;
           
       case 8:
           cout<<"请输入要插入的元素大小及其位置:";
           cin>>elem>>index;
           InsertList(s1,head1,index,elem);
           break;
           
       case 9:
           cout<<"请输入要删除的元素的下标:";
           cin>>index;
           DeleteList(s1,head1,index);
           break;
           
       case 10:
           if(ClearList(s1,head1))
           {
                cout<<"清空静态链表成功。\n";
           }
           break;
           
       case 11:
           BubbleSort(s1,head1);
           break;
           
       case 12:
           InitList(s2);
           FillList(s2,head2);
           MergeList(s1,head1,s2,head2);
           break;
           
       default:
           cout<<"请输入正确的操作数字!\n";
           break;
       }
    }
   
   return 0;
}
 
void Interaction()
{
   cout<<"请输入对应操作的序号:\n";
   cout<<"0:退出程序;\n";
   cout<<"1:建立静态链表,填充元素;\n";
   cout<<"2:输出静态链表;\n";
   cout<<"3:判断静态链表是否为空;\n";
    cout<<"4:求静态链表的长度 ;\n";
   cout<<"5:反转静态链表;\n";
   cout<<"6:查找静态链表指定下标的元素;\n";
   cout<<"7:求出给定元素在静态链表中第一次出现的位置;\n";
   cout<<"8:向静态链表中的指定位置插入元素;\n";
   cout<<"9:删除静态链表中指定位置的元素;\n";
   cout<<"10:清空当前静态链表;\n";
   cout<<"11:将静态链表按照升序排序;\n";
   cout<<"12:将两个静态链表归并到第一个静态链表中并按照升序排列;\n";
}
 
void InitList(SLinkList &s)
//初始化静态链表:将一维数组的各分量链成一个备用链表,s[0].cur为第一个结点,0表示空指针
{
   for(int i=0; i<MAXSIZE-1; i++)
    {
       s[i].cur=i+1;
    }
   s[MAXSIZE-1].cur=0;
}
 
int Malloc(SLinkList &s)//若备用链表空间非空,则返回分配的结点下标,否则返回0
{
   int i=s[0].cur;
   if(i)
    {
       s[0].cur=s[i].cur;//取出一个备用结点,更新下一个可用结点的下标
    }
   return i;
}
 
void Free(SLinkList &s,int index)//将下标为k的空闲节点回收到备用链表中
{
   s[index].cur=s[0].cur;
   s[0].cur=index;
}
 
void FillList(SLinkList &s,int&head)//填充静态链表的元素,注意:head要使用引用传值
{
   cout<<"请输入元素的个数:";
   int listsize;
   cin>>listsize;
   
   head=Malloc(s);//生成头结点
   int r=head;//r是尾结点
   
   cout<<"请输入元素:";
   for(int i=1; i<=listsize; i++)
    {
       int index=Malloc(s);
       if(index)
       {
           cin>>s[index].data;
           s[r].cur=index;
           r=index;//更新尾结点的索引
       }
    }
   s[r].cur=0;//最后指向空指针
   
   cout<<"静态链表是:";
   Output(s,head);
}
 
void Output(SLinkList s,int head)//输出静态链表
{
   if(!IsEmpty(s,head))
    {
       int index=s[head].cur;//第一个结点
       while(index)
       {
           cout<<s[index].data<<" ";
           index=s[index].cur;//更新结点
       }
       cout<<endl;
    }
   else
    {
       cout<<"静态链表为空,无法输出。\n";
    }
}
 
Status IsEmpty(SLinkList s,int head)//判断静态链表是否为空
{
   if(s[head].cur==0)
    {
       return OK;
    }
   return FALSE;
}
 
int ListLength(SLinkList s,int head)//求静态链表的长度
{
   int length=0;
   int index=s[head].cur;
   while(index)
    {
       length++;
       index=s[index].cur;
    }
   return length;
}
 
void ReverseList(SLinkList &s,inthead)//反转静态链表
{
   int p,q;
   p=s[head].cur;
   q=s[p].cur;
   
   s[p].cur=0;
   while(q)
    {
       int index=s[q].cur;//预存下一个结点
       s[q].cur=p;
       p=q;//更新结点
       q=index;
    }
   s[head].cur=p;//最后转换头结点
   
   cout<<"反转后的静态链表是:";
   Output(s,head);
}
 
void GetElem(SLinkList s,int index,inthead)//得到指定下标的元素
{
   if(index<1||index>ListLength(s,head))
    {
       cout<<"位置越界,无法输出。\n";
       return;
    }
   
   int num=1;
   int index2=s[head].cur;
   while(1)
    {
       if(num==index)
       {
           cout<<"第"<<index<<"个元素是:"<<s[index2].data<<endl;
           return;
       }
       num++;
       index2=s[index2].cur;
    }
}
 
void GetIndex(SLinkList s,ElemType elem,inthead)//得到指定元素的下标
{
   int num=1;
   int index=s[head].cur;
   while(index)
    {
       if(s[index].data==elem)
       {
           cout<<"元素"<<elem<<"是静态链表中的第"<<num<<"个元素。\n";
           return;
       }
       num++;
       index=s[index].cur;
    }
   cout<<"未找到,已退出。\n";
}
 
void InsertList(SLinkList &s,inthead,int index,ElemType elem)//插入元素
{
   if(index<1||index>ListLength(s,head))
    {
       cout<<"位置越界,无法插入。\n";
       return;
    }
   
   int num=0;
   int p=head;
   while(num<=index-2)
    {
       num++;
       p=s[p].cur;
    }
   
   int newnode=Malloc(s);
   s[newnode].data=elem;
   s[newnode].cur=s[p].cur;
   s[p].cur=newnode;
    
   cout<<"静态链表是:";
   Output(s,head);
}
 
void DeleteList(SLinkList &s,inthead,int index)//删除结点
{
   if(index<1||index>ListLength(s,head))
    {
       cout<<"位置越界,无法删除。\n";
       return;
    }
   
   int num=0;
   int p=head;
   while(num<=index-2)
    {
       num++;
       p=s[p].cur;
    }
   
   int deletenode=s[p].cur;
   s[p].cur=s[deletenode].cur;
   Free(s,deletenode);//回收被删除的结点
   
   cout<<"静态链表是:";
   Output(s,head);
}
 
Status ClearList(SLinkList &s,inthead)//清空静态链表
{
    int index=s[head].cur;
   while(index)
    {
       int index2=s[index].cur;
       Free(s,index);//回收结点
       index=index2;
    }
   return OK;
}
 
void BubbleSort(SLinkList &s,inthead)//冒泡排序
{
   int i=s[head].cur,j;
   while(i)
    {
       j=s[i].cur;
       while(j)
       {
           if(s[i].data>s[j].data)
           {
                swap(s[i].data,s[j].data);
           }
           j=s[j].cur;
       }
       i=s[i].cur;
    }
   
   cout<<"排序后的静态链表是:";
   Output(s,head);
}
 
void MergeList(SLinkList &s1,inthead1,SLinkList &s2,int head2)
//归并两个静态链表到第一个静态链表中并保持升序
{
   if(!IsEmpty(s1,head1)&&!IsEmpty(s2,head2))
    {
       BubbleSort(s1,head1);//先对两个分静态链表排序
       BubbleSort(s2,head2);
       
       int p=s1[head1].cur,q=s2[head2].cur;
       int index=head1;
       while(p&&q)//当没有链表归并完时
       {
           if(s1[p].data<=s2[q].data)
           {
                s1[index].cur=p;
//因为归并到第一个链表中,所以s1[p].data<=s2[q].data时,只需要改变链表s1的结点指向即可,无需声明新结点
                index=p;//更新“新”静态链表的结点指针
                p=s1[p].cur;//更新未归并的结点的指针
           }
           else
           {
                int newnode=Malloc(s1);//声明新节点,复制到静态链表s1中
                s1[newnode].data=s2[q].data;
                s1[index].cur=newnode;//完成指针转移
                index=newnode;
                q=s2[q].cur;
           }
       }
       
       while(q)//当s1本身完成归并但是s2未完成归并时,将剩余的所有s2的结点全部复制到s1链表中
       {
           int newnode=Malloc(s1);
           s1[newnode].data=s2[q].data;
           s1[index].cur=newnode;
           index=newnode;
           q=s2[q].cur;
       }
       s1[index].cur=0;//终结新链表
       
       if(p)//当s2完成归并但是s1未完成归并时,只需要将“新”s1最后一个元素的指针连接到将要被归并的第一个元素上
       {
           s1[index].cur=p;
       }
       
       cout<<"归并后的静态链表是:";
       Output(s1,head1);
       ClearList(s2,head2);
       return;
    }
   cout<<"静态链表为空,无法归并。\n";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: