/*
* Created by Dev-c++5.11
* @author: Teresa
* @date: 2017-10-06
* @description: 单链表操作
*/
#include
#include
/*函数状态码*/
#define TRUE 1 //成功
#define OK 1
#define FALSE 0 //失败
#define ERROR 0 //错误
#define INFEASIBLE -1 //不可行的
#define OVERFLOW -2 //溢出
#define LNODELENGTH sizeof(LNode) //一个结点所占的空间
typedef int ElemType; //基本数据类型
typedef int Status; //函数的返回值类型
/*单链表的存储结构*/
typedef struct LNode{
ElemType data; // 数据域
struct LNode *next; //指向下一个结点的指针
}LNode, *LinkList;
//初始化线性表L
Status ListInit_L(LinkList &L){
L = (LinkList)malloc(LNODELENGTH); //分配大小为LNODELENGTH的空间 L指向空间的首地址
if (L == NULL){
printf("内存分配失败 初始化链表失败");
exit(INFEASIBLE);
}
L->data = 0;
L->next = NULL;
return TRUE;
}
//销毁线性表L
Status DestroyList_L(LinkList &L){
LinkList p = L, q = p->next;
while (q != NULL){ //当p不是最后一个结点时
free(p); //释放p指向的结点
p = q; //p指向下一个要free的结点
q = p->next;
} //循环结束后 p指向最后一个结点
free(p); //释放最后一个结点的空间
return OK;
};
//将L置为空表
Status ClearList_L(LinkList L){
LinkList p;
while (L->next != NULL){ //当L->next不是NULL 即第二个结点存在时
p = L->next; //p指向第二个结点
L->next = p->next; //L的next指向第三个结点
free(p); //释放第二个结点
}//循环结束时 表中只剩下头结点
return OK;
}
//若L为空表则返回TRUE 否则返回 FALSE
Status ListEmpty_L(LinkList L){
if (L->next == NULL)
return TRUE;
else
return FALSE;
}
//返回L中数据元素的个数
Status ListLength_L(LinkList L){
int sum = 0; //用来存放数据元素的个数
LinkList p= L;
do{ //当p不是最后一个结点时
sum++; //sum自增
p = p->next;
} while (p != NULL);
return sum;
}
//用e返回L中第i个数据元素的值
Status GetElem_L(LinkList L, int i, ElemType * e){
if (i<0 || i>ListLength_L(L)){ //当i小于0或i大于链表的长度时 无法查询第i个数据元素
return INFEASIBLE;
}
LinkList p = L;
int j=0;
while (j <= i){
p = p->next;
j++;
}
return p->data;
}
//返回 L中第一个与e满足关系compare()的数据元素的位序 若不存在 则返回0
Status LocateElem_L(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)){
LinkList p = L;
int i = 0;
while (!compare(p->data, e) && p->next != NULL){
p = p->next;
i++;
} //退出循环有两种可能 一是找到了匹配的元素 二是没有找到 超出了线性表的长度
if (p->next == NULL){
i++;
if (compare(p->data, e))
return i;
else{
return FALSE;
}
}
else{
return i;
}
}
//若cur_e是L的数据元素 且不是第一个 则用pre_e返回它的前驱 否则操作失败 pre_e无定义
Status PriorElem_L(LinkList L, ElemType cur_e, ElemType * pre_e){
LinkList p = L;
if (cur_e == p->data){
printf("此元素没有前驱");
return FALSE;
}
while (p->next->data != cur_e || p == NULL){
p = p->next;
}
if (p == NULL){
printf("超出了线性表的长度\n");
return FALSE;
}
else{
*pre_e = p->data;
return TRUE;
}
}
///若cur_e是L的数据元素 且不是最后一个 则用next_e返回它的前驱 否则操作失败 next_e无定义
Status NextElem_L(LinkList L, ElemType cur_e, ElemType * next_e){
LinkList p = L;
while (p->data != cur_e || p == NULL){
p = p->next;
}
if (p == NULL){
printf("此数据元素没有后驱\n");
return FALSE;
}
else{
*next_e = p->next->data;
return TRUE;
}
}
//在L中的第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert_L(LinkList &L, int i, ElemType e){
LinkList p = L, newp;
int j=0, length = ListLength_L(L);
if (i<0 || i>length+1){ //当i小于0或i大于链表的长度时 无法插入
printf("不可行\n");
return INFEASIBLE;
}
if (i == 1){ //头插
newp = (LinkList)malloc(LNODELENGTH);
if (newp == NULL){
printf("内存分配失败\n");
exit(INFEASIBLE);
}
newp->data = e;
newp->next = L;
return OK;
}
else if (i == length+1){ //尾插
while (p->next != NULL)
p = p->next;
newp = (LinkList)malloc(LNODELENGTH);
if (newp == NULL){
printf("内存分配失败\n");
exit(INFEASIBLE);
}
p->next = newp;
newp->data = e;
newp->next = NULL;
return OK;
}
else{
while (j < i-2){
j++;
p = p->next;
}//循环结束后 p为要插入位置的前一个结点
newp = (LinkList)malloc(LNODELENGTH);
if (newp == NULL){
printf("内存分配失败\n");
exit(INFEASIBLE);
}
newp->next = p->next;
newp->data = e;
p->next = newp;
return TRUE;
}
}
//删除L中的第i个元素 并用e返回其值 L的长度减1
Status ListDelete_L(LinkList &L, int i, ElemType * e){
LinkList p = L,q;
int j = 0, length = ListLength_L(L);
if (i<0 || i>length + 1){ //当i小于0或i大于链表的长度时 无法插入
printf("不可行\n");
return INFEASIBLE;
}
while (j < i - 2){
j++;
p = p->next;
}//循环结束后 p为要删除位置的前一个结点
q = p->next;
p->next = q->next;
free(q);
return OK;
}
//对L的每一个元素调用函数visit 一旦visit()失败 则操作失败
Status ListTraverse_L(LinkList L, void(*visit)(ElemType *)){
LinkList p = L;
while (p != NULL){
visit(&(p->data));
p = p->next;
}
printf("\n");
return 0;
}
//若数据元素a与b相等则返回TRUE 否则返回 FALSE
Status compare(ElemType a, ElemType b){
if (a == b){
return TRUE;
}
else
return FALSE;
}
//输出数据元素
void visit(ElemType *e){
printf("%d ", *e);
}
//已知单链线性表La Lb的元素按值非递减排列
//归并La Lb得到新的单线性链表Lc Lc的元素也按值非递减排列
Status MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc){
LinkList pa = La, pb = Lb;
int i = 2;
if (La == NULL || Lb == NULL){
printf("空表无法合并");
return ERROR;
}
//La和Lb的头结点中最小的data赋给Lc头结点的data
if (pa->data <= pb->data){
Lc->data = La->data;
pa = pa->next;
}
else{
Lc->data = Lb->data;
pb = pb->next;
}
while (pa != NULL || pb != NULL){
if (pa != NULL && pa->data <= pb->data){
ListInsert_L(Lc, i, pa->data);
pa = pa->next;
}
else{
ListInsert_L(Lc, i, pb->data);
pb = pb->next;
}
i++;
}
return OK;
}
//求La和Lb的交集
Status IntersectList_L(LinkList La, LinkList Lb, LinkList Lc){
LinkList pa = La, pb = Lb;
if (pa == NULL || pb == NULL){
printf("空表无法求交集");
return ERROR;
}
int i = 1;
while (pb != NULL){
if (LocateElem_L(La,pb->data,compare)!=0){
if (i == 1) Lc->data = pb->data;
else
ListInsert_L(Lc, i, pb->data);
i++;
}
pb = pb->next;
}
return OK;
}
//求La和Lb的差
Status SubtractList_L(LinkList La, LinkList Lb, LinkList Lc){
LinkList pa = La, pb = Lb;
if (pa == NULL || pb == NULL){
printf("空表无法求差");
return ERROR;
}
int i = 1;
while (pb != NULL){
if (LocateElem_L(La, pb->data, compare) == 0){
if (i == 1) Lc->data = pb->data;
else
ListInsert_L(Lc, i, pb->data);
i++;
}
pb = pb->next;
}
return OK;
}
int main(){
LinkList La,Lb,Lc;
ListInit_L(La);
ListInit_L(Lb);
ListInit_L(Lc);
La->data = 3;
ListInsert_L(La, 2, 5);
ListInsert_L(La, 3, 8);
ListInsert_L(La, 4, 11);
Lb->data = 2;
ListInsert_L(Lb, 2, 4);
ListInsert_L(Lb, 3, 6);
ListInsert_L(Lb, 4, 8);
ListInsert_L(Lb, 5, 9);
ListInsert_L(Lb, 6, 11);
ListInsert_L(Lb, 7, 15);
ListInsert_L(Lb, 8, 20);
printf("链表La\n");
ListTraverse_L(La, visit);
printf("链表Lb\n");
ListTraverse_L(Lb, visit);
printf("La Lb的并集Lc\n");
MergeList_L(La, Lb, Lc);
ListTraverse_L(Lc,visit);
ClearList_L(Lc); //将Lc置为空表
printf("La与Lb的交集Lc\n");
IntersectList_L(La, Lb, Lc);
ListTraverse_L(Lc, visit);
ClearList_L(Lc); //将Lc置为空表
SubtractList_L(La, Lb, Lc);
printf("La与Lb的差Lc\n");
ListTraverse_L(Lc, visit);
return 0;
}