/*******************************************************************************
/* <PRE>
/* 版权所有 : -
/* 模块名 : 线性表
/* 文件名 : linklist.cpp
/* 功能描述 : 线性表的链式表示与实现
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************
/* 数据类型和常量定义
/******************************************************************************/
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
/******************************************************************************
/* 数据结构声明
/******************************************************************************/
/* 线性表的单链表存储结构 */
typedef struct LNode {
ElemType data;
struct LNode *next;
}LNode, *LinkList;
/*******************************************************************************
/* <FUNC>
/* 函数名 : GetElem_L
/* 功能 : 获取线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : L为带头结点的单链表的头指针, 当第i个元素存在时, 其值赋给e并返回OK, 否则返回ERROR
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status GetElem_L(LinkList L, int i, ElemType &e) {
int j = 0;
struct LNode *p = NULL;
p = L->next; j = 1; //初始化, p指向第一个结点, j为计数器
while(p && j < i) { //顺指针向后查找, 直到p指向第i个元素或p为空
p = p->next; ++j;
}
if (!p || j > i) return ERROR; //第i个元素不存在
e = p->data;
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : CreateList_L
/* 功能 : 构造线性链表
/* 参数 : -
/* 返回值 : -
/* 备注 : 逆位序输入n个元素的值, 建立带表头结点的单链线性表L
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void CreateList_L(LinkList &L, int n) {
printf("input %d integers: \n", n);
struct LNode *p = NULL;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //先建立一个带头结点的单链表
for (int i = n; i > 0; --i) {
p = (LinkList)malloc(sizeof(LNode)); //生成新结点
scanf("%d", &p->data);
p->next = L->next; L->next = p; //插入到表头
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListInsert_L
/* 功能 : 在线性表中插入元素
/* 参数 : -
/* 返回值 : -
/* 备注 : 在带头结点的单链线性表L中第i个位置之前插入元素e
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListInsert_L(LinkList &L, int i, ElemType e) {
struct LNode *p = L; int j = 0;
struct LNode *s = NULL;
while (p && j < i - 1) { p = p->next; ++j; } //寻找第i-1个结点
if (!p || j > i - 1) return ERROR; //i小于1或者大于表长
s = (LinkList)malloc(sizeof(LNode)); //生成新结点
s->data = e; s->next = p->next;
p->next = s;
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListDelete_L
/* 功能 : 删除线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : 在带头结点的单链线性表L中, 删除第i个元素, 并由e返回其值
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListDelete_L(LinkList &L, int i, ElemType &e) {
struct LNode *p = L; int j = 0; struct LNode *q = NULL;
while (p->next && j < i - 1) { //寻找第i个结点, 并令p指向其前趋
p = p->next; ++j;
}
if (!(p->next) || j > i - 1) return ERROR; //删除位置不合法
q = p->next; p->next = q->next; //删除并释放结点
e = q->data; free(q);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : MergeList_L
/* 功能 : 归并线性表
/* 参数 : -
/* 返回值 : -
/* 备注 : 已知单链线性表La和Lb的元素按值非递减排列
/* 归并La和Lb得到新的单链线性表Lc, Lc的元素也按值非递减排列
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
struct LNode *pa = NULL; struct LNode *pb = NULL; struct LNode *pc = NULL;
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 { pc->next = pb; pc = pb; pb = pb->next; }
}
pc->next = pa ? pa : pb; //插入剩余段
free(Lb); //释放Lb的头结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListTraverse_L
/* 功能 : 遍历线性表
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListTraverse_L(LinkList &L, Status (*Visit)(ElemType)) {
struct LNode *p = L->next; //略过头结点
while (p) {
Visit(p->data);
p = p->next;
}
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Visit
/* 功能 : 访问线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status Visit(ElemType e)
{
printf("%d ", e);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
LinkList L; ElemType e;
CreateList_L(L, 2);
//插入元素
if (OK == ListInsert_L(L, 1, 55)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 0, 56)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 7, 57)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 4, 58)) printf("insert succeed!\n");
ListTraverse_L(L, Visit); printf("\n");
//删除元素
if (OK == ListDelete_L(L, 1, e)) printf("delete %d succeed!\n", e);
if (OK == ListDelete_L(L, 3, e)) printf("delete %d succeed!\n", e);
ListTraverse_L(L, Visit); printf("\n");
//获取元素
if (OK == GetElem_L(L, 2, e)) printf("get elem %d succeed!\n", e);
//链表合并
LinkList La, Lb, Lc;
CreateList_L(La, 3);
CreateList_L(Lb, 4);
MergeList_L(La, Lb, Lc);
ListTraverse_L(Lc, Visit);
}
/* <PRE>
/* 版权所有 : -
/* 模块名 : 线性表
/* 文件名 : linklist.cpp
/* 功能描述 : 线性表的链式表示与实现
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************
/* 数据类型和常量定义
/******************************************************************************/
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
/******************************************************************************
/* 数据结构声明
/******************************************************************************/
/* 线性表的单链表存储结构 */
typedef struct LNode {
ElemType data;
struct LNode *next;
}LNode, *LinkList;
/*******************************************************************************
/* <FUNC>
/* 函数名 : GetElem_L
/* 功能 : 获取线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : L为带头结点的单链表的头指针, 当第i个元素存在时, 其值赋给e并返回OK, 否则返回ERROR
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status GetElem_L(LinkList L, int i, ElemType &e) {
int j = 0;
struct LNode *p = NULL;
p = L->next; j = 1; //初始化, p指向第一个结点, j为计数器
while(p && j < i) { //顺指针向后查找, 直到p指向第i个元素或p为空
p = p->next; ++j;
}
if (!p || j > i) return ERROR; //第i个元素不存在
e = p->data;
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : CreateList_L
/* 功能 : 构造线性链表
/* 参数 : -
/* 返回值 : -
/* 备注 : 逆位序输入n个元素的值, 建立带表头结点的单链线性表L
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void CreateList_L(LinkList &L, int n) {
printf("input %d integers: \n", n);
struct LNode *p = NULL;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //先建立一个带头结点的单链表
for (int i = n; i > 0; --i) {
p = (LinkList)malloc(sizeof(LNode)); //生成新结点
scanf("%d", &p->data);
p->next = L->next; L->next = p; //插入到表头
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListInsert_L
/* 功能 : 在线性表中插入元素
/* 参数 : -
/* 返回值 : -
/* 备注 : 在带头结点的单链线性表L中第i个位置之前插入元素e
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListInsert_L(LinkList &L, int i, ElemType e) {
struct LNode *p = L; int j = 0;
struct LNode *s = NULL;
while (p && j < i - 1) { p = p->next; ++j; } //寻找第i-1个结点
if (!p || j > i - 1) return ERROR; //i小于1或者大于表长
s = (LinkList)malloc(sizeof(LNode)); //生成新结点
s->data = e; s->next = p->next;
p->next = s;
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListDelete_L
/* 功能 : 删除线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : 在带头结点的单链线性表L中, 删除第i个元素, 并由e返回其值
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListDelete_L(LinkList &L, int i, ElemType &e) {
struct LNode *p = L; int j = 0; struct LNode *q = NULL;
while (p->next && j < i - 1) { //寻找第i个结点, 并令p指向其前趋
p = p->next; ++j;
}
if (!(p->next) || j > i - 1) return ERROR; //删除位置不合法
q = p->next; p->next = q->next; //删除并释放结点
e = q->data; free(q);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : MergeList_L
/* 功能 : 归并线性表
/* 参数 : -
/* 返回值 : -
/* 备注 : 已知单链线性表La和Lb的元素按值非递减排列
/* 归并La和Lb得到新的单链线性表Lc, Lc的元素也按值非递减排列
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
struct LNode *pa = NULL; struct LNode *pb = NULL; struct LNode *pc = NULL;
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 { pc->next = pb; pc = pb; pb = pb->next; }
}
pc->next = pa ? pa : pb; //插入剩余段
free(Lb); //释放Lb的头结点
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : ListTraverse_L
/* 功能 : 遍历线性表
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status ListTraverse_L(LinkList &L, Status (*Visit)(ElemType)) {
struct LNode *p = L->next; //略过头结点
while (p) {
Visit(p->data);
p = p->next;
}
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Visit
/* 功能 : 访问线性表中的元素
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
Status Visit(ElemType e)
{
printf("%d ", e);
return OK;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
LinkList L; ElemType e;
CreateList_L(L, 2);
//插入元素
if (OK == ListInsert_L(L, 1, 55)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 0, 56)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 7, 57)) printf("insert succeed!\n");
if (OK == ListInsert_L(L, 4, 58)) printf("insert succeed!\n");
ListTraverse_L(L, Visit); printf("\n");
//删除元素
if (OK == ListDelete_L(L, 1, e)) printf("delete %d succeed!\n", e);
if (OK == ListDelete_L(L, 3, e)) printf("delete %d succeed!\n", e);
ListTraverse_L(L, Visit); printf("\n");
//获取元素
if (OK == GetElem_L(L, 2, e)) printf("get elem %d succeed!\n", e);
//链表合并
LinkList La, Lb, Lc;
CreateList_L(La, 3);
CreateList_L(Lb, 4);
MergeList_L(La, Lb, Lc);
ListTraverse_L(Lc, Visit);
}