码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构读书笔记----------第二章 线性表

时间:2015-10-25 22:26:06      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:

2.1 线性表的定义

  线性结构的特点是数据元素之间是一种线性关系,在一个线性表中,数据元素的类型是相同的,或者说线性表是由同一类型的数据元素构成的线性结构.综上所诉:线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列.

2.2 线性表的顺序存储以及运算实现

//线性顺序存储的定义
#define Maxsize 100
typedef int DataType;
typedef struct {
        DataType data[Maxsize];
        int last;     //用来记录线性表中最后一个元素在数组中的位置
}SeqList;
SeqList L;

//顺序表的初始化
SeqList *Init_SeqList()
{
        SeqList *L;
        L=new SeqList;      //分配空间
        if(L)                   //空间分配成功
        {
                L->last=-1;    
                return L;
        }
        else                        //申请不成功
                return -1;
}

int Insert_SeqList(SeqList L,int i,DataType x)   //插入算法
{
            int j;
            if(L->last+1>=Maxsize)    //如果超过了预定空间大小
                return -1;
            if(i<1||i>L->last+2)  //插入的位置是从1到n+1,n==L->last+1
                return -1;
            for(j=L->last;j>=i-1;j--)
                L->data[j+1]=L->data[j];
            L->data[i-1]=x;
            L->last++;
            return 1;
}

int Delete_SeqList(SeqList L,int i)     //删除算法
{
            if(i<1||i>L->last+1)     //删除的位置从1到n,不存在则返回错误代码
                  return 0;
            for(int j=i;j<=L->last;j++)    //向前移动一位
                L->data[j-1]=L->data[j];
            L->last--;
            return 1;
}

int Location_SeqList(SeqList L,DataType x)   //按值查找
{
            int j=0;
            while(j<=L->last&&L->data[j]!=x)
                j++;
            if(j>L->last)
                return -1;
            else 
                return i;
}

2.3  顺序表的应用举例

//将顺序表重新排列成以a1为界的两部分,a1前面的数据元素的值均比a1小,a1后面数据元素的值都比a1大
void part(SeqList *L)
{
        int i,j;
        DataType x,y;
        x=L->data[0];
        for(i=1;i<=L->last;i++)
        {
                if(L->data[i]<x)
                {
                        y=L->data[i];
                        for(j=i-1;j>=0;j--)    //前面的所有数据都向后移动
                        {
                                L->data[j+1]=L->data[j];   
                        }
                        L->data[0]=y;
                }
        }
}

//有序表的合并算法,A和B是从小到大的升序排列
void Mymerge(SeqList A,SeqList B,SeqList *C)
{
            int i,j,k;
            i=j=k=0;
            while(i<=A.last&&j<=B.last)   //依次扫描顺序表A和B中的数据元素
            {
                    if(A.data[i]<B.data[j])
                    {
                            C->data[k]=A.data[i];
                            i++;
                            k++;
                    }
                    else
                    {
                            C->data[k]=B.data[j];
                            j++;
                            k++;
                    }
              }
              while(i<=A.last)   //把A中剩下的值赋给C
              {
                    C->data[k]=A.data[i];
                    i++;
                    k++;
              }
              while(j<=B.last)    //把B中剩下的值赋给C
              {
                    C->data[k]=B.data[j];
                    j++;
                    k++;
              }
              C->last=k-1;
}
    
//比较线性表大小的算法
int compare(int A[],int B[],int m,int n)
{
        int i,j,ms,ns;
        int AS[],BS[];
        i=0;
        while(i<=m&&i<=n&&A[i]==B[i])    
            i++;        //找最大的共同前缀
        ms=ns=0;
        for(j=i;j<n;j++)
        {
                AS[ms]=A[j];
                ms++;
        }
        for(j=i;j<n;j++)
        {
                BS[ms]=B[j];
                ns++;
        }
        if(ms==ns&&ms==0)
            return 0;     //AS,BS是空表,则A和B是相等
        else
            if(ms==0&&ns>0||ms>0&&ns>0&&AS[0]<BS[0])     //A表小于B表
                    return -1;
            else    
                    return 1;                             //A表大于B表
}

2.4  线性表的链存储和运算实现

typedef struct Node    //链表的结构定义
{
        DataType data;
        struct Node *next;
}LNode,*LinkList;

//建立链表,第一种从头部插入,头插法
LinkList *Init_LinkList()
{
        LinkList L;
        LNode s;
        int x;
        L=NULL;    //首先置为空表
        cin>>x;
        while(x!=Flag)
        {
            s=new LNode;
            s->data=x;
            s->next=L;
            L=s;
            cin>>x;
        }
        return L;
}

//从尾部插入
LinkList *Init_LinkList2()
{
        LinkList  L;
        LNode *r,*s;
        L=r=NULL;
        int x;
        cin>>x;
        while(x!=Flag)
        {
                s=new LNode;
                s->data=x;
                if(L==NULL)      //第一个节点的处理
                        L=s;
                else
                        r->next=s;    //其他节点的处理
                r=s;      //r指向新的尾节点
                cin>>x;
         }
         return L;
}

//带头节点的求表长
int length_LinkList1(LinkList L)
{
        LNode *p;
        int i=0;
        p=L;
        while(p->next)
        {
                p=p->next;
                i++;
        }
        return i;   //P指向第i个节点
}

//不带头节点的单链表求表长
int length_LinkList2(LinkList L)
{
        LNode *p;
        int i=0;
        p=L;
        while(p)
        {
            i++;
            p=p->next;
        }
        return i;   //指向第i+1个节点
}

//按序号查找,带头节点
int Get_LinkList(LinkList L,int i)
{
        int j=1;
        LNode *p;
        p=L->next;
        while(p!=NULL&&j<i)
        {
                p=p->next;
                j++:
        }
        return p;
}

//按值查找,带头节点的链表
int *Location_LinkList(LinkList L,DataType x)
{
        LNode *p;
        p=L->next;
        while(p!=NULL&&p->data!=x)
            p=p->next;
        return p;
}

//插入运算,关键在于找到前一个节点
LinkList Insert_LinkList(LinkList L,int i,DataType x)
{
        LNode *p,*s;
        p=Get_LinkList(LinkList L,i-1);
        if(p==NULL)    //如果第i-1个节点不存在
                return 0;
        else
        {
                s=new LNode;
                s->data=x;
                s->next=p->next;
                p->next=s;
                return 1;
        }
}

//删除节点
LinkList Detele_LinkList(LinkList L,int i)
{
            LNode *s,*p;
            p=Get_LinkList(L,i-1);
            if(p==NULL)
                return -1;
            else
                if(p->next==NULL)
                        return 0;
                else
                {
                        s=p->next;     //s指向第i个节点
                        p->next=s->next;   //从链表中删除节点s
                        delete s;               //释放空间
                        return 1;
                }
}


//将两个单循环链表链接起来,r1,r2是循环链表的尾指针
        p=r1->next;    //保留H1的头指针
        r1->next=r2->next->next;   //头尾相接
        delete r2->next;   //删除H2的头节点
        r2->next=p;   //组成循环链表

//双向链表的定义
typedef struct DLnode 
{
            DataType data;
            struct DLnode *prior,*next;
}DLnode,*DLinkList;

//插入操作,s插到p的节点前面
        s->prior=p->prior;
        p->prior->next=s;
        s->next=p;
        p->prioe=s;

//删除节点
        p->prior->next=p->next;
        p->next->prior=p->prior;
        delete p;

2.5 链表的应用

//链表的倒置,采用头插法的原理
void reverse(LinkList L)
{
        LNode *p,*s;
        p=L->next;
        L->next=NULL;
        while(p)
        {
            s=p;
            p=p->next;
            s->next=L;       //将当前节点插到头节点后面(注意哲理的"后面"的理解,由于头插的方向)
            L->next=s;
        }
}

//删除链表中重复节点的算法
void pur_LinkList(LinkList L)
{
        LNode *p,*s,*q;
        p=L->next;
        while(p)
        {
                q=p;
                while(q->Next)
                {
                        if(q->next->data==p->data)
                        {
                                s=q->next;
                                q->next=s->next;
                                delete s;
                        }
                        else
                            q=q->next;
                }
                p=p->next;
        }
}

//两个链表的归并算法,A,B是递增有序的,归并成一个递减的有序链表C
LinkList merge(LinkList A,LinkList B)
{
        LinkList C;
        LNode *p,*q;
        p=A->next;
        q=B->next;
        C=A;
        C->next=NULL:
        delete B;
        while(p&&q)
        {
                if(p->data<q->data)
                {
                        s=p;
                        p=p->next;
                }
                else{
                        s=q;
                        q=q->next;
                }
                s->next=C->next;    //头插
                C->next=s;
        }
        if(p==NULL)
                p=q;
        while(p)      //将剩余的节点一个个摘下,插入倒C表的头部
        {
                s=p;
                p=p->next;
                s->next=C->next;
                C->next=s;
        }
}

2.6  算法应用

1.一个递增有序的线性表,插入一个x,插入到合适的位置,序列还是递增有序

int InsertSeq(int A[],int num,DataType x)
{
        int i=num;
        while(i>=0&&A[i]>x)
           {
                A[i+1]=A[i];   //边找边移动
                i--;
            }
        A[i+1]=x;
        num++;
        return 1;
}

 2.假设在长度大于1的单循环链表中,既无头节点也无指针,s为指向链表中某个节点的指针,编写删除节点s的直接前驱节点

void Deletepre(LNode *s)
{
        LNode *p,*q;
        p=s;
        while(p->next==s)
        {
                q=p;
                p=p->next;
        }
        q->next=s;
        delete p;
}

3.两个单链表A和B分别代表两个集合,其元素递增,编写一个函数求A和B的交际,同样以递增的单链表存储

LinkList *inter(LinkList A,LinkList B)
{
        LNode *p,*q,*r,*s;
        LNode *C;
        C=new LNode;
        r=C;
        p=A;
        q=B;
        while(p&&q)
        {
                if(p->data>q->data)
                    p=p->next;
                else if(p->data==q->data)
                {
                        s=new LNode;
                        s->data=p->data;
                        r->next=s;
                        r=s;
                        p=p->next;
                        q=q->next;
                }
                else    
                    q=q->next;
        r->next=NULL;
        r=C->next;
        delete C;
        return r;
}

4. 单链表L是一个递减的有序表,时编写一个高效算法,删除表中值大于min且小于max的节点,同时释放被删除节点的空间

LinkList delete(LinkList L,int min,int max)
{
        LNode *p,*q,*s;
        if(L->next)
        {
                p=L->next;
                s=L;
                while(p->data>=max)
                {
                    s=p;
                    p=p->next;
                }
                while(p!=L&&p->data>min)
                    p=p->next;
                while(s->next!=p)
                {
                        k=s->next;
                        s->next=k->next;
                        delete k;
                }
        }
}

5. 线性表用顺序存储,将前m个元素和后n个元素互换

void process(SeqList *L,int m,int n)
{
        int i,k;
        DataType x;
        if(m<=n)
        {
                for(i=1;i<=m;i++)
                    x=L->data[0];
                    for(k=1;k<=L->last;k++)
                        L->data[k-1]=L->data[k];
                    L->data[L->last]=x;
        }
        else
        {
                for(i=1;i<=n;i++)
                x=L->data[L->last];
                for(k=L->last-1;k>=0;k--)
                    L->data[k+1]=L->data[k];
                L->data[0]=k;        
        }
}

6.带头节点的单链表L的节点是按整数值递增的,将x插入,使L有序

LinkList *insert(LinkList L,int x)
{
        LNode *p,*s;
        p=L;
        while(p->next&&x>p->next->data)
        {
                p=p->next;
        }
        s=new LNode;
        s->data=x;
        s->next=p->next;
        p->next=s;
        return L;
}

  

数据结构读书笔记----------第二章 线性表

标签:

原文地址:http://www.cnblogs.com/SqLver/p/4909517.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!