数据结构笔记——线性表

文章目录

  • 基础概念
  • 顺序表
    • 优点:
    • 缺点:
      • 代码实现顺序表的基本运算
  • 链表
    • 单链表
      • 代码实现顺序表的基本运算
        • 1. 单链表的建立
        • 2. 单链表的查找
        • 3. 链表的插入
        • 4. 链表的删除
      • 循环链表
      • 双向链表
      • 顺序表和链表比较:

基础概念

  线性表是由n个元素构成的有限序列,其中数据元素的个数n定义为表的长度,n=0时称为空表,是一个线性结构。
  逻辑特征:对于非空的线性表,有且仅有一个开始节点,有且仅有一个终端节点。
  线性表的存储结构是一种随机存取的存储结构

顺序表

  顺序表是用向量实现的线性表,是一种随机存储结构,其特点是以元素在计算机内物理位置上的紧邻来表示线性表中数据元素之间相邻的逻辑关系

优点:

  • 顺序表的存储密度高
  • 在结点等长时,可以随机存取顺序表中的任意元素

缺点:

  • 在做插入或删除运算时,须移动大量元素。
  • 由于顺序表要求占用连续的存储空间,因此在给长度变化较大的顺序表预先分配空间时,必须按最大空间分配,使存储空间不能得到充分利用。
  • 顺序表的容量难以扩充

代码实现顺序表的基本运算

#include
#include
#include
#define MAXSIZE 1024

typedef char datatype;
typedef struct
{
    datatype data[MAXSIZE];
    int last;
}sequenlist;
sequenlist *L;

//建立顺序表L

sequenlist *Create()
{
    int i=0;
    char ch;
    L = (sequenlist*)malloc(sizeof(sequenlist)); //分配顺序表空间
    L->last=-1;
    printf("请输入顺序表L中的元素,以‘#’结束\n");

    while((ch=getche())!='#')
    {
        L->data[i++]=ch;
        L->last++;

    }
    return L;
}

// 将新节点x插入顺序表L的第i个位置上
int Insert(sequenlist*L,char x,int i)
{
    int j;
    if((L->last)>=MAXSIZE-1)   //表空间溢出
    {
        printf("overflow\n");
        return 0;
    }
    else
        if((i<1)||(i>(L->last)+2))   //位置不合法
        {
            printf("error");
            return 0;
        }
    else
    {
        for(j=L->last;j>=i-1;j--)

            L->data[j+1]=L->data[j];
        L->data[i-1]=x;
        L->last=L->last+1;
    }

    return 1;
}

// 输出顺序表L的内容
void Output(sequenlist*L)
{
    int i;
    printf("\n顺序表L的元素为:");
    for(i=0;i<=L->last;i++)
        printf("%c",L->data[i]);
    printf("\n");
}

//从顺序表中删除第i个位置上的元素
int Delete(sequenlist*L,int i)
{
    int j;
    if((i<1)||(i>L->last+1))
    {
        printf("error\n");
        return 0;
    }
    else
    {
        for(j=i;j<=L->last;j++)
            L->data[j-1]=L->data[j];
        L->last--;
    }
    return 1;
}
//主函数
void main()
{
    char ch;
    int i,ret;
    L=Create();
    printf("\n请输入插入字符:");
    scanf("%c",&ch);
    printf("\n请输入插入位置:");
    scanf("%d",&i);
    ret=Insert(L,ch,i);
    if(ret)
        Output(L);
    printf("\n请输入删除位置:");
    scanf("%d",&i);
    ret=Delete(L,i);
    if(ret)
        Output(L);
}

链表

  链表是用一组任意的存储单元来存放线性表的元素,这组存储单元既可以是连续的,也可以是不连续的。
  存储数据元素信息的域称作数据域。
  存储后继元素存储位置的域称作指针域。

单链表

  • 链表的每个结点只包含一个指针域。

  • 头结点指向开始结点,终端节点的指针域为空。

代码实现顺序表的基本运算

1. 单链表的建立

// 头插法
linklist*CreatListF()
{
    char ch;
    linklist *head,*s;
    head=NULL;
    while((ch=getche())!='#')
    {
        s=(linklist*)malloc(sizeof(linklist));
        s->data=ch;
        s->next=head;
        head=s;
    }
    return head;
}
// 尾插法
linklist *CreatListR()
{
    char ch;
    linklist *head,*s,*r;
    head=(linklist*)malloc(sizeof(linklist));;
    r=head;
    while(ch=getche()!='#')
    {
        s=(linklist*)malloc(sizeof(linklist));
        s->data=ch;
        r->next=s;
        r=s;
    }
    r->next=NULL;
    return head;
}

2. 单链表的查找

1> 按序号查找

//再带头结点的单链表head中查找第i个结点,若找到,则返回该结点的存储位置否则返回NULL
linklist *Get(linklist *head,int i)
{
    int j;
    linklist *p;
    p = head;j=0;
    while((p->next!=NULL)&&(j<i))
        {
            p=p->next;
            j++;
        }
        if(j==i)
            return p;
        else
            return NULL;
}

2> 按值查找

// 在带有头节点的单链表head中查找其结点值等于key的节点,若找到则返回节点位置p,否则返回NULL
linklist *Locate(linklist *head,datatype key)
{
    linklist *p;
    p=head->next;
    while((p!=NULL)&&(p->next!=key))
        p=p->next;
    if(p==NULL)
        return NULL;
    else
        return p;
}

3. 链表的插入

// 链表的插入
void InsertAfter(linklist *p,datatype x)
{
    linklist *s;
    s=(linklist*)malloc(sizeof(linklist));
    s->data=x;
    s->next=p->next;
    p->next=s;
}

4. 链表的删除

// 链表的删除
void Delete(linklist *p,linklist*head)
{
    linklist *q;
    q=head;
    while(q->!p)
        q=q->next;
    q->next=p->next;
    free(p);
}

循环链表

  循环链表是另一种形式的链式存储结构,它的特点是表中最后一个结点的指针域只想头结点,从表中的任意结点出发均可找到表中其他结点。

双向链表

  双向链表的结点有两个指针域,一个指向直接后继,另一个指向直接前趋,基本原理很简单,算法描述时注意要改两个方向的指针就好。

顺序表和链表比较:

  1. 一般来说,存储密度越大,存储空间的利用率越高,显然,顺序存储结构的存储密度为1,而链式存储结构的存储密度小于1.

  2. 顺序存储结构是一种损及存取结构,便于元素的随机访问,每个元素都可以在时间复杂度为O(1)的情况下迅速存储;而链式存储结构中,为了访问某个结点,必须从头指针开始顺序查找,时间复杂度为O(n)。所以对于一个表,只进行查找操作而很少进行插入和删除操作时,采用顺序存储结构为宜。

  3. 顺序存储结构进行插入和删除时,要移动大量元素,而链式存储结构只需要修改相应的指针等,因此对于频繁进行元素插入和删除操作的线性表,采用链式存储结构为宜

你可能感兴趣的:(日常学习笔记,数据结构,C,语言)