数据结构之线性结构之线性表

一. 线性表及其实现

如何表示多项式:f(x)=a0+a1x+...+an-1xn-1+anxn

  1. 多项式的项数n;
  2. 各项系数 ai 及指数 i

顺序存储结构直接表述:一般数组

 

顺序存储结构表示非零项:结构数组

方法二中如果要对各项进行相加时,注意两项的指数需要按照降序或者升序排列

 

链表结构存储非零项

 

 线性表:由同类型数据元素(可以是自定义的结构体等)构成有序序列的线性结构

 

线性表的顺序存储实现:利用数组的连续存储空间顺序存放线性表的各元素

 

#define MAXSIZE 10
typedef struct {
    int Data[MAXSIZE];
    int Last;
}List;

List L, *PtrL;
//访问下标为i的元素:L.Data[i]或者PtrL->Data[i]
//线性表的长度:L.Last+1或者PtrL->Last+1;由于数组从0开始,而Last表示数组的下标

 主要操作的实现

初始化

List *MakeEmpty()
{
    List *PtrL = new List;//new的操作:申请存储空间并且初始化
    PtrL->Last = -1;
    return PtrL;
}

查找

int Find(int X, List *PtrL)
{
    int i = 0;
    while (i<=PtrL->Last&&PtrL->Data[i]!=X)//i<ptrl的长度,并没找到x时继续往下找
    {
        i++;
    }
    if (i>PtrL->Last)
    {
        return -1;
    }
    else
    {
        return i;
    }
}

插入:先移动再插入

由于数组从0开始,第 i 个位置对应的下标数为 i-1

void Insert(int X, int i, List *PtrL)//X为插入的数字,i为插入的位置
{
    if (PtrL->Last == MAXSIZE - 1)//先检查表是否还有空间,如果表空间已满,不能再插入
    {
        printf("表满");
        return;
    }
    if(i<1||i>PtrL->Last+1)
    {
        printf("插入位置不合法");
        return;
    }
    for (int j = PtrL->Last; j >=i-1; j--)
    {
        PtrL->Data[j + 1] = PtrL->Data[j];//从数组最后一个数开始往后移一,直到移动到i-1位置位置,此时i-1的位置为空
    }
    PtrL->Data[i - 1] = X;// 插入新元素
    PtrL->Last++; //last指向的位置也要往后移动1
    return;
}

删除:后面元素依次往前移动

 

 

void Delete( int i, List *PtrL)//i为删除的位置
{
    if (i<1 || i>PtrL->Last + 1)
    {
        printf("插入位置不合法");
        return;
    }
    for (int j = i; j <=PtrL->Last; j++)
    {
        PtrL->Data[j - 1] = PtrL->Data[j];//从第i位置开始,后面依次往前移动一个位置
    }
    PtrL->Last--; //last指向的位置也要往后移动1
    return;
}

线性表的链式存储实现:逻辑上相邻,物理存储位置上不相邻

插入删除不需要移动数据元素,只需要修改链

 

 

typedef struct Node {
    int Data;
    struct Node *Next;
} ListNode;

ListNode LN, *PtrlN;

主要操作

求表长

int Length(ListNode *PtrlN)
{
    ListNode *p = PtrlN;//定义一个临时变量指向表的第一个结点
    int j = 0;
    while (p)
    {
        p = p->Next;
        j++;            //当前p指向第j个结点
    }
    return j;
}

查找

按序号查找:FindKth;

ListNode *FindKth(int K, ListNode *PtrlN)//K为需要找到的序号为K的,即第K个
{
    ListNode *p = PtrlN;
    int i = 1;
    while (p!=NULL&&i<K)
    {
        p = p->Next;
        i++;
    }
    if (i == K) return p;
    else  return NULL;
}

按元素查找:FindKth;

ListNode *Find(int X, ListNode *PtrlN)//X为需要查找的元素
{
    ListNode *p = PtrlN;
    while (p!=NULL&&p->Data!=X)
    {
        p = p->Next;
    }
    return p;
}
//返回值为null,则说明没有找到

插入

先找到插入点之前的那个结点,即i-1的结点

ListNode *Insert(int X, int i, ListNode *PtrlN)//X为插入的数字,i为插入的位置
{
    ListNode *p;
    if (i==1)//新结点插入在表头
    {
        ListNode *s = new ListNode;
        s->Data = X;
        s->Next = PtrlN;
        return s;
    }
    p = FindKth(i - 1, PtrlN);
    if (p==NULL)
    {
        printf("参数i出错");
        return NULL;
    }
    else
    {
        ListNode *s = new ListNode;
        s->Data = X;
        s->Next = p->Next;
        p->Next = s;   //注意,此处和上面一个语序不能颠倒,否则s的next还是s
        return PtrlN;
    }
}

一段存储空间存放链表,ptrlN和p都只是指向其中的一个指针,指向哪个位置,就从该位置开始一直到链表的最后

 删除

 

 

 删除一定要记住释放删除点的内存

ListNode *Delete(int i, ListNode *PtrlN)//X为插入的数字,i为插入的位置
{
    ListNode *p;
    if (i == 1)//删除结点在表头
    {
        ListNode *s = PtrlN;
        if (PtrlN != NULL)PtrlN = PtrlN->Next;
        else return NULL;
        delete(s);   //一定记住要释放链表中删除点的内存
        return PtrlN;
    }
    p = FindKth(i - 1, PtrlN);
    if (p == NULL)
    {
        printf("参数i出错");
        return NULL;
    }
    else if (p->Next == NULL)
    {
        printf("参数i出错");
        return NULL;
    }
    else
    {
        ListNode *s = p->Next;
        p->Next = s->Next;
        delete(s);   //注意,此处和上面一个语序不能颠倒,否则s的next还是s
        return PtrlN;
    }
}

 

 

 

广义表:

  1. 线性表的推广;
  2. 广义表中元素可以是单元素也可以是另一个广义表
  3.  union

 

多重链表:链表的节点可能同时隶属于多个链;结点的指针域会有多个;

 

 

 

 

 

 

posted @ 2018-05-13 20:15  小雪SS  阅读(344)  评论(0编辑  收藏  举报