数据结构之单链表

数据结构之单链表代码如下:
//========================head===============================================
//head.h
#ifndef _hhlisst_
#define _hhlisst_

#define TRUE        
#define FALSE        0
#define OK           1 //成功
#define ERROR        0 //失败(错误)
#define INFEASIBLE  -1 //不可行的
#define MEMOVERFLOW -2 //(内存)溢出
#define UNDERFLOW   -4 //(数组下标)下溢

#define ENDELEM -9999 //序列结束元素(为方便演示而设)

typedef char ElemType;       //元素类型ElemType为int

typedef int Status; 
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;

#endif


//=============================================================================

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

Status InitList_L(LinkList &L)
//参数L要用引用参数&L或指针形式*L,因作为表头指针的变量L的值需要改变
{
LNode *h;         //如果 LinkList h; 后面的形式也要改变;
h = (LNode *)malloc(sizeof(LNode));//申请头结点空间
if (!h)          //若未申请成功,
exit(MEMOVERFLOW); //则终止程序(退出码MEMOVERFLOW)
h->next = NULL;  //头结点链域置空
L = h;           //表头指针指向头结点
return OK; 
}//InitList_L

void DestroyList_L(LinkList &L)
//参数L不必用引用参数&L或指针形式*L,因只用变量L的值。用之是为与InitList_L形式统一
{
LNode *p, *q;
p = L;      //当前结点为头结点
while (p != NULL)
{ //若当前结点存在,则释放并处理下一结点
q = p->next; //下一结点
free(p);     //释放当前结点空间
p = q;       //下一结点作为当前结点
}//end while
//L = NULL;
}//DestroyList_L



LNode *GetNode_L(LinkList L, int i)
{
LNode *p;
int c = 0; //计数器置0
p = L;     //当前结点为头结点
//从头结点开始搜索:
while ((c < i) && (p->next != NULL))
{//若未到位且下一结点存在,则搜索下一结点
c++;        //计数器加1
p = p->next;//下一结点作为当前结点
}//end while
if (c == i)  //若搜索了i步,
return p;   //则返回最后搜索点;
else         //否则,
return NULL;//返回NULL
}//GetNode_L



Status ListInsert_L(LinkList L, int i, ElemType e)
{
LNode *pre, *pnew;
pre = GetNode_L(L, i-1);     //找出第i结点前驱
if (!pre) return ERROR;      //若未找到则退出 
pnew = (LNode *)malloc(sizeof(LNode));//申请新结点空间
pnew->data = e;         //新结点值置为e
pnew->next = pre->next; //新结点指向pre的后继
pre->next = pnew;       //pre指向新结点
return OK;
}//ListInsert_L
 



Status ListDelete_L(LinkList L, int i, ElemType &e)
{
LNode *pre, *pnode;
pre = GetNode_L(L, i-1); //找出待删结点的前驱
if (!pre) 
return ERROR;  //若未找到则退出
pnode = pre->next;       //待删结点 
pre->next = pnode->next; //pre指向待删结点的后继
e = pnode->data; //待删结点值置于e       
free(pnode);      //释放待删结点
return OK;
}//ListDelete_L


void CreateList1_L(LinkList &L, ElemType *v)
{
LNode *last, *p;
ElemType *c;
last = L;  //初始时,尾结点即头结点
c = v;     //c指向当前结点值位置
while (*c != '$')
{//只要结点值未用完,便生成新结点
p = (LNode *)malloc(sizeof(LNode));//申请新结点空间
p->data = *c;   //新结点值
p->next = NULL; //新结点作新尾结点
last->next = p; //新结点作原尾结点后继
last = p;       //新尾结点
c++; //下一结点值
}//end while
}//CreateList_L

void CreateList2_L(LinkList &L, ElemType *v)
{
LNode *last, *p;
ElemType *c;
last = L;  //初始时,尾结点即头结点
c = v;     //c指向当前结点值位置
while (*c != '$')
{//只要结点值未用完,便生成新结点
p = (LNode *)malloc(sizeof(LNode));//申请新结点空间
p->data = *c;   //新结点值
p->next = last->next; 
last->next=p;//从表尾到表头逆向建表
c++; //下一结点值
}//end while
}//CreateList_L


Status InsertSucc_L(LNode *pre, ElemType e)
{
LNode *pnew;
pnew = (LNode *)malloc(sizeof(LNode));//申请新结点空间
pnew->data = e;         //新结点值置为e
pnew->next = pre->next; //新结点指向pre的后继
pre->next = pnew;       //pre指向新结点
return OK;
}//InsertSucc_L



void ShowList_L(LinkList L) //显示单链表
{
LNode *p;
int i;

printf("H→[0]→");
p = L->next;
i = 1;
while (p != NULL)
{
printf("[%d]%c→", i, p->data);
p = p->next;
i++;
}
printf("\n");
}//ShowList_L


//保序归并:归并非递减单链表La和Lb为非递减单链表Lc
void MergeList_L(LinkList La, LinkList Lb, LinkList &Lc)
{
LNode *pa, *pb, *pc;

pa = La->next; //a表当前指针初始为指向首结点
pb = Lb->next; //b表当前指针初始为指向首结点
Lc = La;       //La头结点作Lc头结点
pc = Lc;       //c表尾指针初始为指向头结点 
//归并:
while(pa && pb)
{//只要pa,pb均指向表内结点便继续
if (pa->data <= pb->data) //若a表当前结点小,
{
pc->next = pa; //c表尾结点指向pa
pc = pa;       //c表新的尾指针
pa = pa->next; //a表当前指针后移(b指针不动);
}
else            //否则(b表当前结点小),
{
pc->next = pb; //c表尾结点指向pb
pc = pb;       //c表新的尾指针
pb = pb->next; //b表当前指针后移(a指针不动)
}
//end if
}//end while
//上个循环结束后,La和Lb一定有一个表的结点被
//用完,而另一个表的结点未用完,处理之:
while(pa)
{//若La未用完,则将剩余结点依次加入Lc
pc->next = pa; //c表尾结点指向pa
pc = pa;       //c表新的尾指针
pa = pa->next; //a表当前指针后移
}//end while
while(pb)
{//若Lb未用完,则将剩余结点依次加入Lc
pc->next = pb; //c表尾结点指向pb
pc = pb;       //c表新的尾指针
pb = pb->next; //b表当前指针后移
}//end while
}//MergeList_L

//=============================================================================

void main(void)
{
LinkList h, La, Lb, Lc;

ElemType e;

InitList_L(h); //初始化单链表h

CreateList1_L(h, "ABC$"); //生成单链表h→[]→A→B→C

printf("原表:\n"); ShowList_L(h);

ListInsert_L(h, 2, 'y'); //在A之后插入y

ListInsert_L(h, 1, 'x'); //在A之前插入x

printf("插入x,y后:\n"); ShowList_L(h);

ListDelete_L(h, 1, e);   //删除x

printf("删除%c后:\n", e); ShowList_L(h);

DestroyList_L(h); //销毁单链表h

//测试保序归并:
InitList_L(La); InitList_L(Lb); //初始化表La,Lb

CreateList1_L(La, "ACD$"); //生成单链表La→[]→A→C→D

CreateList1_L(Lb, "BCE$"); //生成单链表Lb→[]→B→C→E

printf("La表:\n"); ShowList_L(La);

printf("Lb表:\n"); ShowList_L(Lb);

MergeList_L(La, Lb, Lc);

printf("Lc表:\n"); ShowList_L(Lc);
//
getchar();
DestroyList_L(La);
DestroyList_L(Lb);
DestroyList_L(Lc);

}//end main

//==========================================================================


posted @ 2014-05-07 22:14  dreamsyeah  阅读(129)  评论(0编辑  收藏  举报