数据结构实验一

2014-11-24 02:27:47 · 作者: · 浏览: 1
实验1链表的插入和删除
【实验内容】
设有两个无头结点的单链表,头指针分别为ha,hb,链中有数据域data,链域next,两链表的数据都按递增序存放,现要求将hb表归到ha表中,且归并后ha仍递增序,归并中ha表中已有的数据若hb中也有,则hb中的数据不归并到ha中,hb的链表在算法中不允许破坏。
/************************************/  
/****                            ****/  
/****    数据结构 实验一         ****/  
/****                            ****/  
/****    作者 : 王小康          ****/  
/****    时间 : 2013年11月11日  ****/  
/****                            ****/  
/************************************/  
  
#include  
#include  
#include  
typedef int ElemType;  
  
/*单项链表的声明*/  
typedef struct LNode{  
    ElemType data;  
    struct LNode *next;  
}LNode,*LinkList;  
  
/*正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表*/  
void CreateList(LinkList &L,int n)  
{  
    int i;  
    LinkList p,q;  
    L=(LinkList)malloc(sizeof(LNode)); // 生成头结点  
    L->next=NULL;  
    q=L;  
    printf("请输入%d个数据\n",n);  
    for(i=1;i<=n;i++)  
    {  
        p=(LinkList)malloc(sizeof(LNode));  
        scanf("%d",&p->data);    
        q->next=p;  
        q=q->next;  
    }  
    p->next=NULL;  
}  
  
// vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同  
void ListTraverse(LinkList L,void(*vi)(ElemType))  
{// 初始条件:线性表L已存在  
 // 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败  
    LinkList p=L->next;  
    while(p)  
    {  
     vi(p->data);  
     p=p->next;  
    }  
    printf("\n");  
}  
  
/*ListTraverse()调用的函数(类型要一致)*/  
void visit(ElemType c)   
{  
    printf("%d ",c);  
}  
  
/*    归并函数                      */  
/* 参数:两个已经存在的单链表       */  
/* 返回值:归并后新的单链表的头结点 */  
LinkList MergeList(LinkList La, LinkList Lb)  
{  
    LinkList pa, pb, pc, Lc;  
    pa = La->
next; pb = Lb->next; Lc = pc = La; // 用La的头结点作为Lc的头结点 while(pa&&pb) { if(pa->data < pb->data) { pc->next = pa; pc = pa; pa = pa->next; } else if (pa ->data > pb->data ) { pc->next = pb; pc = pb; pb = pb->next; } else //(pa ->data = pb->data ) { pc->next = pa; pc = pa; pa = pa->next; pb = pb->next; } } pc->next = pa pa:pb; // 插入剩余段 return Lc; } void main() { LinkList ha, hb, hc; printf("非递减输入ha, "); CreateList(ha,5); // 正位序输入n个元素的值 printf("非递减输入hb, "); CreateList(hb,5); // 正位序输入n个元素的值 printf("Ha = "); ListTraverse(ha,visit); // 输出链表Ha的内容 printf("Hb = "); ListTraverse(hb,visit); // 输出链表Ha的内容 hc = MergeList(ha,hb); // 按非递减顺序归并Ha和Hb,得到新表Hc printf("归并后:"); printf("Hc = "); ListTraverse(hc,visit); // 输出链表Hc的内容 }

【小结】
1.建立链表分为头插法(逆位序)建表和尾插法(正位序)建表,两种建表方式不同,输出也不同。
2.在归并函数中,没有额外的申请空间,而是在原有的空间玩指针游戏。但是从函数中可以看出,归并后ha链表已经被打乱,而hb链表不变。其实ha和hc指向同一处。