数据结构4:链表(下)

一、链表的种类

不修改头指针
易找前驱结点
不分首位结点
单项链表
加表头
加表头链表
向后插入法构造链表问题
双向
双向链表
循环
循环链表
约瑟夫问题
双向循环链表
内存管理问题
双向加表头循环链表
有序链表构造问题

二、常用种类示例

1.单向链表

结点只含一个链域,通常指向后继结点

空表

非空表

在这里插入图片描述

2.单向加头链表

设计带监督元的链表,是为了更方便的对链表进行操作。

空表

在这里插入图片描述

非空表

在这里插入图片描述

头结点,不存放元素,优势用来存储特殊值。

3.单向加尾链表

是带有表尾监督元的链表。利用监督元可以使查找操作更加方便

空表

在这里插入图片描述

非空表

在这里插入图片描述

4.单向循环链表

空表
在这里插入图片描述

非空表

在这里插入图片描述

可巡视一周

5.单向加头循环链表

空表

在这里插入图片描述

非空表

在这里插入图片描述

兼有二者优点

6.双向简单链表

结点含有两个链域,一个指向前驱,一个指向后继。可以很方便的进行左右搜索

空表

在这里插入图片描述

非空表

在这里插入图片描述

7.双向加头循环链表

双向加头循环链表是一种具有全部附加特征的完善形式

空表

在这里插入图片描述

非空表

在这里插入图片描述

三、单向加尾链表的查找

用设置尾监督元的方式完成链表的查找,基本思想与顺序表的带监督元的顺序查找是一样的。

ptr searchB(ptr p,ptr last,int x)
{
    last->data = x;//设置监督元
    while(p->data!=x)
        p=p->next;//没有找到,继续
    if(p!=last)return p;//查找成功
    return NULL;//查找不成功
}

四、单向加头循环链表的删除

如果频繁的进行查找、插入、删除,不妨采用加头循环链表,表头结点兼做表尾结点。

int deleteBC(ptr h,element_type x)
{
    ptr f,p;
    f=h,p=h->next;//设置搜索指针初始值
    h->head=x;//设置监督元
    while(p->data!=x)f=p,p=p->next;
    if(p==h) return 0;//删除不成功
    f->next = p->next;
    free(p);
    return 1;//删除成功
}

五、双向链表的插入和删除

结点类型定义为:

typedef struct dnode
{
    element_type data;//值域
    struct dnode *Llink,*Rlink;//左右链域
}dnode,*dptr;//结构类型名指针类型名

在这里插入图片描述

链接关系的特点

在这里插入图片描述

1.插在p的左侧:

在这里插入图片描述
在这里插入图片描述

q->Rlink=p;
q->Llink=q->Llink;
p->Llink=q;
q->Llink->Rlink=q;

2.删除p所指结点

在这里插入图片描述

在这里插入图片描述

p->Rlink->Llink=p->Llink;
p->Llink->Rlink=p->Rlink;

六、有序链表的构造

一般不能要求用户输入的数据必须是有序,因此需要设计排序的方法。下面的方法为边输入数据,边排序的高效处理方法。插入位置一般分为三种情况:1.小于表头结点,插在表头处;2.大于表尾结点,插在表尾处;3.插在表“中间”p->data<p-data<s->data。为了提高算法效率,这里就可以使用加头有序循环链表

ptr createlinkBC()
{
	ptr head,f,s,p;
    element_type x;
    head = new snode;
    head->data=MAX;//MAX公共监督元
    head->next=head;//构造空链表
    scanf("%d",&x);
    while(x!=End_elm)
    {
        p = new snode;
        p->next=x;
        f=head,s=f->next;//设置搜索指针初始值
    	while(s->data<x) f=s,s=s->next;//有序搜索
    	f->next=p,p->next=s;//有序插入
    	scanf("%d",&x);//读入下一个元素
    }
    return head;
}

七、示例:稀疏多项式求和问题

P = 8 + 10 x 2 + 5 x 100 Q = 2 x 2 + 9 x 17 5 x 100 + 15 x 130 P = 8+10x^2+5x^{100} \\ Q = 2x^2+9x^{17}-5x^{100}+15x^{130}

求P+Q,并且在P表上求和。

如何存储多项式? 链式

如何求和? 有序合并

方法? 加头有序循环链表存储多项式

结点结构和主调程序

typedef struct node
{
    int ceof;//系数域
    int exp; //指数域
    struct node *next;
}snode,*ptr;

void main()
{
    ……
    ha = createlinkdBC();//创建多项式
    hb = createlinkdBC();//创建多项式
    ha = add_n(ha,hb);
    ……
}

在这里插入图片描述

ptr creatlinkedBC()
{
	ptr head,f,s,p;
    element_type x;
    head = new snode;
    head->exp=MAX;
    head->next=head;
    scanf("%d %d",&coef,&exp);//输入系数和指数
    while(exp!=-1)
    {
        p = new snode;
        p->ceof=coef;
        p->exp=exp;//创建新结点
        f=head,s=f->next;//设置搜索指针初始值
    	while(s->exp<exp) f=s,s=s->next;//有序搜索
    	f->next=p,p->next=s;//有序插入
    	scanf("%d %d",&coef,&exp);//读入下一个元素
    }
    return head;
}

在这里插入图片描述

ptr add_n(ptr ha,ptr hb)
{
    ptr p,q,last_p,last_q;
    int val;
    p = ha->next;
    q = hb->next;
    last_p = ha;
    pre_q = hb;
    while(p!=ha&&q!=hb)
    {
        if(p->exp>q->exp)//第一种情况
        {
            pre_q->next=q_next;//从hb链表删除q结点
            last_p->next=q;//插入ha链表
            q->next=p;
            last_p=last_p->next;//调整前驱指针位置
            q=pre_q->next;
        }else if(p->exp<q->exp)//第二种情况
        {
            last_p=p;
            p=p->next;
        }else//第三种情况,指数相同的合并
        {
            val = p->ceof+q->ceof;
            if(val!=0)//插入一个,删除一个
            {
                p->ceof = val;
                pre_q->next=q->next;
                free(q);
                last_p=p;
                p=p->next;
                q=pre_q->next;
            }
            else//删除稀疏相加后为0的结点
            {
                last_p->next=p->next;
                pre_q->next=q->next;
                free(p);
                free(q);
                p=last_p->next;
                q=pre_q->next;
            }
        }
    }
    if(q!=hb)//插入hb中剩余的链表
    {
        last_p->next=q;
        while(q->next!=hb) q=q->next;
        q->next=p;
    }
    free(hb);
    return ha;
}

猜你喜欢

转载自blog.csdn.net/jiangSummer/article/details/105370152