DataStructure-2-线性表

来源:互联网 发布:日本进出口数据 编辑:程序博客网 时间:2024/05/16 13:52

2.1 顺序表

  2.1.1 顺序表

          线性表的顺序存储结构称为顺序表,指的是用一段地址连续的存储单元一次存储线性表的数据元素.

  

    2.1.2 顺序表的实现

          struct 和 typedef struct使用区别:点击打开链接

 程序实例:

    SeqList.h:

#ifndef SEQLIST_H
#define SEQLIST_H

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int ElemType; //指用标识符ElemType代表int类型

typedef struct seqlist
{
    ElemType *data_address; //存储空间首地址
    int length;    //当前长度
    int size;      //允许存储的最大容量
}seqlist;          //别名顺序表

void Init(seqlist *L); //初始化函数
int Insert(seqlist *L,int pos,ElemType e); //按照位置插入
int Delete(seqlist *L,int pos);        //按照位置删除
int Locate(seqlist *L,ElemType e);        //按值查找
void PrintList(seqlist *L);         //遍历操作
void Destroy(seqlist *L);   //销毁

#endif


  SeqList.c:

#include "SeqList.h"

const int MAXLISTSIZE=20; //预设的存储空间最大容量

/*初始化数组*/
void Init(seqlist *L)
{
    printf("-------Start Init()--------\n");
    L->data_address = (ElemType*)malloc(MAXLISTSIZE*sizeof(ElemType));

    if(L->data_address == NULL) //内存分配失败,程序退出
    {
        exit(1);
    }
    L->size = MAXLISTSIZE;
    L->length = 0;
    printf("-------End Init()---------\n");
}
int Locate(seqlist *L,ElemType e)
{
    int i = 1;
    ElemType *p = L->data_address; //p的初值为第一个元素的存储位置
    while(i<=L->length)
     {
        if(p[i]==e)
        {
            break;
        }
        i++;
    }
    if(i<=L->length)
    {
        return i;
    }else{
        return 0;
    }
}

int Insert(seqlist *L,int pos,ElemType e)
{
    int j;
    if(pos < 1||pos >L->length+1) //插入位置不合法,合法位置是1~表长+1
    {
        printf("Insert Error pos\n");
        return 0;
    }
    if(L->length>=L->size) //当前存储空间已满,无法插入
    {
        printf("Insert Error full of Store Space \n");
        return 0;
    }
    for(j=L->length-1;j>=pos-1;--j)
    {
        L->data_address[j+1] = L->data_address[j];  //插入位置及之后的元素后移
    }
    L->data_address[pos-1] = e; //插入e
    ++L->length;    //表长增加1
    return 1;
}

int Delete(seqlist *L,int pos)
{
    int i;

    if(L->length == 0)  //删除位置下溢
    {
        printf("Delete seqlist is Empty!");
             return 0;
    }

    if(pos<1||pos>L->length) //删除位置不正确
    {
        printf("Delete pos is illegal!");
        return 0;
    }

    for(i=pos;i<L->length;i++)
    {
        L->data_address[i-1] = L->data_address[i];
    }
    L->length--;
    return 1;

}

void PrintList(seqlist *L)
{
    int n,i;
        n = L->length;

    for(i=0;i<=n;i++)
    {
        printf("%6d\n",L->data_address[i]);
    }

}

void Destory(seqlist *L)
{
    free(L->data_address);
    L->length = 0;
    L->size = 0;
}



  main.c:

#include <stdio.h>
#include "SeqList.h"

int main(void)
{

    int i;
    seqlist L;
    ElemType e;
    Init(&L);

    srand((unsigned int)time(0));//srand(seed)用于给rand()函数设定种子
    for(i=1;i<=10;i++)
    {
        Insert(&L,i,rand()%30);  //插入10个元素
    }

    PrintList(&L);

    printf("length:%d, Size:%d\n",L.length,L.size);

    int j = Locate(&L,7);

     if(j==0) //查找5所在的位置
    {
        printf("Not find 5 at the seqlist\n");
    }else{
        printf("Locate is : %d\n",j);
    }

    PrintList(&L);

    Destory(&L);


    return 0;
}



                   
   2.2单链表

  

  2.2.1  单链表

 单链表是用一组任意的存储单元存放线性表的元素,这组存储单元可以连续也可以不连续,甚至可以零散分布在内存中的任意位置.

 


 节点示意图:


  2.2.2 单链表的实现

 

LinkList.h:


#ifndef LINKLIST_H
#define LINKLIST_H


#include <stdio.h>
#include <stdlib.h>


typedef int ElemType;


typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node,*LinkList;  //Node 代表常规节点,LinkList代表链表及头节点


int Init(LinkList *L); //初始化
void CreateLinkListHead(LinkList *L,int n); //头插法创建单链表
void CreateLinkListTail(LinkList *L,int n); //尾插发创建单链表
int Insert(LinkList *L,int i,ElemType e); //在i位置插入元素e
int Delete(LinkList *L,int i,ElemType *e); //删除i位置元素
int Locate(LinkList *L,ElemType e); //按值查找
int ClearList(LinkList *L); //整表删除
void PrintList(LinkList *L); //遍历


#endif
        


LinkList.c:


#include "LinkList.h"


int Init(LinkList *L)
{
    (*L) = (LinkList)malloc(sizeof(Node));
    if(*L == NULL)
    {
        printf("Init LinkList Error");
        return 0;
    }
    return 1;
}


void CreateLinkListHead(LinkList *L,int n)
{
    Node *p;
    int i;
    srand(time(0));
    *L = (LinkList)malloc(sizeof(Node));
    (*L)->next = NULL;     //(*L)相当于头节点
    for(i=0;i<n;i++)
    {
        p = (Node *)malloc(sizeof(Node)); //创建一个节点

        p->data = rand()%100 + 1;  //使用rand函数向节点添加内容
        p->next = (*L)->next;    //将节点添加上
        (*L)->next = p;
    }


}


void CreateLinkListTail(LinkList *L,int n)
{
    Node *p,*r;
    int i;
    srand(time(0));
    *L=(LinkList)malloc(sizeof(Node)); //头节点
    r=*L;
    for(i=0;i<n;i++)
    {
        p=(Node *)malloc(sizeof(Node));
        p->data = rand()%100 +1;
        r->next = p;
        r=p;   //r指针后移到p
    }
    r->next = NULL;
}

int Insert(LinkList *L,int i,ElemType e)
{
    Node *p,*r;
    int j=1;
    r=(*L);
    while(r&&j<i)
    {
        r=r->next;
        ++j;
    }


    if(!r || j>i)
    {
        return 0;
    }


    p=(Node *)malloc(sizeof(Node));
    p->data = e;
    p->next = r->next;
    r->next = p;


    return 1;
}


int Delete(LinkList *L,int i,ElemType *e)
{
    int j;
    Node *p,*q;
    p= *L;
    j=1;
    //查找要删除的位置
    while((p->next) && j<i)
    {
        p = p->next;
        ++j;
    }

/*错误写法:会导致删除正确位置之后的一位

     p= *L->next;
    j=1;
    //查找要删除的位置
    while(p && j<i)
    {
        p = p->next;
        ++j;
    }

*/
    //判断删除位置是否合法
    if(!(p->next) || j>i)
    {
        return 0;
    }
    q = p->next;
    p->next = q->next;
    *e = q->data;
    free(q);


    return 1;

}

int Locate(LinkList *L,ElemType e)
{
    Node *p;
    p=(*L)->next;
    int i=1;
    while(p)
    {


        if(p->data == e)
        {
            return i;
        }
        i++;


        p=p->next;
    }
    return 0;
}

int ClearList(LinkList *L)
{
    Node *p,*q;
    p=(*L)->next;
    while(p)
    {
        q=p->next;
        free(p);


        p=q;
    }
    (*L)->next = NULL;
    return 1;
}


void PrintList(LinkList *L)
{
    Node *p;
    p=(*L)->next;
    while(p)
    {
        printf(" %d ",p->data);
        p=p->next;
    }
    printf("\n");
}


main.c


#include "LinkList.h"


int main(void)
{
  //  Node *L;
    LinkList L;
    int e;
    //printf("%d\n",*L);
    Init(&L);
    //CreateLinkListHead(&L,10);
    CreateLinkListTail(&L,10);
    PrintList(&L);


    Insert(&L,4,10);
    PrintList(&L);


    Delete(&L,4,&e);
    printf("Delete:%d\n",e);
    PrintList(&L);


    printf("Locate:%d\n",Locate(&L,9));


    PrintList(&L);

    ClearList(&L);
    PrintList(&L);


    return 0;
}


2.3循环链表

2.3.1循环链表

    将单链表中终端节点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为但循环链表,简称循环链表.

2.3.2原理

   


若使用尾指针,则查找开始节点和终端节点都很方便.如下:



2.4 双链表

2.4.1双链表

   在循环链表中,虽然从任一节点出发可以扫描到其他节点,但要找到其前驱节点,则需要遍历整个循环链表.如果希望快速确定表中任一节点的前驱节点,可以在单链表的每个节点中再设置一个指向其前驱节点的指针域,这样就形成了双链表.

2.4.2原理


循环双链表的插入操作:



循环双链表删除操作:








2.5 静态链表

2.5.1 静态链表

    静态链表是用数组来表示单链表,用数组元素的下标来模拟单链表的指针.

    静态链表:给那些没有指针的高级语言设计的一种实现单链表能力的方法.

 






0 0
原创粉丝点击