数据结构之单链表
数据结构之单链表代码如下:
//========================head===============================================
//head.h
#ifndef _hhlisst_
#define _hhlisst_
#define TRUE
1
#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
//==========================================================================