高一凡-数据结构第2章-线性表

2.2.1线性表的顺序表示和实现

结构体如下:

struct Sqlist
{
    ElemType *elem;
    int length;
    int listsize;
};

指针域是一个类型指针,用于顺序存储数据,两个标志位,length标志表当前存储数据个数,listsize标志表可容纳的数据量。

函数列表
void InitList(Sqlist &L); --初始化
void DestoryList(Sqlist &L);–销毁
void ClearList(Sqlist &L);–清空
Status ListEmpty(Sqlist L);–表空为真
int ListLength(Sqlist L);–返回表长
Status GetElem(Sqlist L, int i, ElemType &e);–获取表中元素值
int LocateElem(Sqlist L, ElemType e, Status(*compare)
Status PriorElem(Sqlist L, ElemType cur_e, ElemType &pre_e);找前驱元素
Status NextElem(Sqlist L, ElemType cur_e, ElemType &next_e);找后继元素
Status ListInsert(Sqlist &L, int i, ElemType e);插入
Status ListDelete(Sqlist &L, int i, ElemType &e);删除
void ListTraverse(Sqlist &L, void(*visit)(ElemType&));遍历
Status equal(ElemType c1, ElemType c2);附加函数,判等
int comp(ElemType a, ElemType b);比较
void print(ElemType c);打印
void print1(ElemType &c);
void print2(ElemType c);

1.初始化

传入引用型顺序表结构L,对于L的指针域进行分配最大顺序空间,同时初始化L的数据长度,以及顺序表的可用长度。

void InitList(Sqlist &L)
{
	L.elem = (ElemType*)malloc(sizeof(ElemType) * LIST_INIT_SIZE);
	if (!L.elem)
		exit(OVERFLOW);
	L.length = 0;
	L.listsize = LIST_INIT_SIZE;
}

2.销毁与清空

销毁即free掉分配给L指针域的空间,传入的是引用。

void DestoryList(Sqlist &L)
{
	free(L.elem);
	L.elem = NULL;
	L.length = 0;
	L.listsize = 0;
}

清空就比较简单,直接将L的当前长度置为0,再次使用时,会覆盖掉原来的值。

void ClearList(Sqlist &L)
{
	L.length = 0;
}

3.判空与长度

判定条件,L的当前长度为0

Status ListEmpty(Sqlist L)
{
	if (L.length == 0)
		return TRUE;
	else
		return FALSE;
}

int ListLength(Sqlist L)
{
	return L.length;
}

4.获取元素值与位置

Status GetElem(Sqlist L, int i, ElemType &e)
{
	if (i<1 || i>L.length)
		return ERROR;
	e = *(L.elem + i - 1);//注意这里是i-1,数据从*elem开始
	return OK;
}

//这里的compare可以看成equal函数,当二者相等时判1,否则判0。

int LocateElem(Sqlist L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 1;
	ElemType *p = L.elem;
	while (i <= L.length && !compare(*p++, e))
	++i;
	if (i <= L.length)
		return i;
	else
		return 0;
}

//寻找前一个节点

Status PriorElem(Sqlist L, ElemType cur_e, ElemType &pre_e)
{
	int i = 1;
	ElemType *p = L.elem + 1;
	while (i <= L.length &&*p != cur_e)
	{
		p++;
		i++;
	}

	if (i > L.length)
		return ERROR;
	else
	{
		pre_e = *--p;
		return OK;
	}
}

//寻找后一个结点

Status NextElem(Sqlist L, ElemType cur_e, ElemType &next_e)
{
	int i = 1;
	ElemType *p = L.elem;
	while (i < L.length && *p != cur_e)
	{
		p++;
		i++;
	}
	if (i == L.length)
		return ERROR;
	else
	{
		next_e = *++p;
		return OK;
	}
}

Status ListInsert(Sqlist &L, int i, ElemType e)
{
	ElemType *newbase, *p, *q;

	if (i < 1 || i >L.length + 1)
		return ERROR;
	if (L.length == L.listsize)
	{
		newbase = (ElemType*)realloc(L.elem, (L.listsize + LIST_INCREMENT) * sizeof(ElemType));
		if (!newbase)
			exit(OVERFLOW);
		L.elem = newbase;
		L.listsize += LIST_INCREMENT;
	}

	q = L.elem + i - 1;
	for (p = L.elem + L.length - 1; p >= q; --p)
		*(p + 1) = *p;
	*q = e;
	++L.length;
	return OK;
}

Status ListDelete(Sqlist &L, int i, ElemType &e)
{
	ElemType *p, *q;
	if (i<1 || i>L.length)
		return ERROR;
	p = L.elem + i - 1;
	e = *p;
	q = L.elem + L.length - 1;
	for (++p; p <= q; ++p)
		*(p - 1) = *p;
	L.length--;
	return OK;
}
void ListTraverse(Sqlist &L, void(*visit)(ElemType&))
{
	ElemType *p = L.elem;
	int i;
	for (i = 1; i <= L.length; i++)
		visit(*p++);
	printf("\n");
}

实现文件2:func2-2.cpp

#include"C1.H"
Status equal(ElemType c1, ElemType c2)
{
	if (c1 == c2)
		return TRUE;
	else
		return FALSE;
}

int comp(ElemType a, ElemType b)
{
	if (a == b)
		return 0;
	else
		return (a - b) / abs(a - b);
}

void print(ElemType c)
{
	printf("%d", c);
}

void print1(ElemType &c)
{
	printf("%d ", c);
}

void print2(ElemType c)
{
	printf("%c", c);
}

主函数

#include "C1.H"

Status sq(ElemType c1, ElemType c2)
{
	if (c1 == c2 * c2)
		return TRUE;
	else
		return FALSE;
}

void dbl(ElemType &c)
{
	c *= 2;
}

int main()
{
	Sqlist L;
	ElemType e, e0;
	Status i;
	int j, k;
	InitList(L);
	printf("初始化L后,L.length = %d,L.listsize = %d,L.elem = %u\n", L.length, L.listsize, L.elem);
	
	for (j = 1; j <= 5; j++)
		i = ListInsert(L, 1, j);
	printf("在L的表头插入1-5之后,*L.elem = ");
	for (j = 1; j <= 5; j++)
		printf("%d ", *(L.elem + j - 1));

	printf("\n调用ListTraverse()函数,依次输出表L中的元素:");
	ListTraverse(L, print1);
	i = ListEmpty(L);
	printf("L.length = %d,L.listsize = %d,", L.length, L.listsize);
	printf("L.elem = %u,L是否为空?i = %d\n\n", L.elem, i);

	ClearList(L);
	i = ListEmpty(L);
	printf("L.length = %d,L.listsize = %d,", L.length, L.listsize);
	printf("L.elem = %u,L是否为空?i = %d,", L.elem, i);

	for (j = 1; j <= 10; j++)
		ListInsert(L, j, j);
	printf("在标为插入1-10之后,L = ");
	ListTraverse(L, print1);
	printf("L.length = %d,L.listsize = %d,L.elem = %u\n", L.length, L.listsize, L.elem);

	ListInsert(L, 1, 0);
	printf("在L的表头插入0后,L.length = %d,L.listsize = %d,L.elem = %u\n ", L.length, L.listsize, L.elem);

	GetElem(L, 5, e);
	ListTraverse(L, print1);
	printf("第5个元素值为 %d ", e);
	for (j = 10; j <= 11; j++)
	{
		k = LocateElem(L, j, equal);
		if (k)
			printf("第 %d 个元素的值为 %d\n", k, j);
		else
			printf("没有值为 %d 的元素\n", j);
	}

	for (j = 3; j <= 4; j++)
	{
		k = LocateElem(L, j, sq);
		if (k)
			printf("第 %d 个元素的值为 %d 的平方\n", k, j);
		else
			printf("没有值为 %d 的平方的元素\n", j);
	}

	for (j = 1; j <= 2; j++)
	{
		GetElem(L, j, e0);
		i = PriorElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无前驱\n", e0);
		else
			printf("元素%d的前驱为%d\n", e0, e);
	}

	for (j = ListLength(L) - 1; j <= ListLength(L); j++)
	{
		GetElem(L, j, e0);
		i = NextElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无后继\n", e0);
		else
			printf("元素%d的后继为%d\n", e0, e);
	}
	k = ListLength(L);
	for ( j = k+1; j >= k; j--)
	{
		i = ListDelete(L, j, e);
		if (i == ERROR)
			printf("%d个元素删除失败\n", j);
		else
			printf("%d个元素删除成功,值为%d\n", j, e);
	}

	ListTraverse(L,dbl);
	printf("L的元素加倍后L = ");
	ListTraverse(L, print1);
	DestoryList(L);
	printf("销毁L后,L.length = %d,L.listsize = %d,L.elem = %u\n", L.length, L.listsize, L.elem);
	return 0;
}

2.2.2换一种写法

头文件c1.h

// c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



#include<string.h> // 字符串函数头文件
#include<ctype.h> // 字符函数头文件
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
#include<stdlib.h> // atoi(),exit()
#include<io.h> // eof()
#include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
#include<sys/timeb.h> // ftime()
#include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
// 函数结果状态代码。在教科书第10页
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
// #define INFEASIBLE -1 没使用
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
typedef int ElemType;

struct LNode
{
	ElemType data;
	LNode *next;
};
typedef LNode *LinkList;

void InitList(LinkList &L);
void DestoryList(LinkList &L);
void ClearList(LinkList &L);
Status ListEmpty(LinkList L);

int ListLength(LinkList L);

Status GetElem(LinkList L, int i, ElemType &e);

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
//寻找前一个节点
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
//寻找后一个结点
Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);

Status ListInsert(LinkList &L, int i, ElemType e);
Status ListDelete(LinkList &L, int i, ElemType &e);

void ListTraverse(LinkList &L, void(*visit)(ElemType));


Status equal(ElemType c1, ElemType c2);
int comp(ElemType a, ElemType b);

void print(ElemType c);
#endif

实现文件1func2-2.cpp

 // func2-2.cpp 几个常用的函数
#include"C1.H"
 Status equal(ElemType c1,ElemType c2)
 { // 判断是否相等的函数
   if(c1==c2)
     return TRUE;
   else
     return FALSE;
 }

 int comp(ElemType a,ElemType b)
 { // 根据a<、=或>b,分别返回-1、0或1
   if(a==b)
     return 0;
   else
     return (a-b)/abs(a-b);
 }

 void print(ElemType c)
 { // 以十进制整型的格式输出元素的值
   printf("%d ",c);
 }

 void print1(ElemType &c)
 { // 以十进制整型的格式输出元素的值(设c为引用类型)
   printf("%d ",c);
 }

 void print2(ElemType c)
 { // 以字符型的格式输出元素的值
   printf("%c ",c);
 }

实现文件2:bo2-2.cpp

#include"C1.H"

void InitList(LinkList &L)
{
	L = (LNode*)malloc(sizeof(LNode));
	if (!L)
		exit(OVERFLOW);
	L->next = NULL;
}

void DestoryList(LinkList &L)
{
	LinkList q;
	while (L)
	{
		q = L->next;
		free(L);
		L = q;
	}

}
void ClearList(LinkList &L)
{
	LinkList p = L->next;
	L->next = NULL;
	DestoryList(p);
}

Status ListEmpty(LinkList L)
{
	if (L->next)
		return FALSE;
	else
		return TRUE;
}

int ListLength(LinkList L)
{
	int i = 0;
	LinkList q = L->next;
	while (q)
	{
		i++;
		q = q->next;
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType &e)
{
	int j = 1;
	LinkList q = L->next;
	while (q && j < i)
	{
		j++;
		q = q->next;
	}
	if (!q || j > i)
		return ERROR;
	e = q->data;
	return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	LinkList p = L->next;
	while (p)
	{
		i++;
		if (compare(p->data, e))
			return i;
		p = p->next;
	}
	return 0;
}
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	LinkList q, p = L->next;
	while (p->next)
	{
		q = p->next;
		if (q->data == cur_e)
		{
			pre_e = p->data;
			return OK;
		}
		p = q;
	}
	return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	LinkList p = L->next;
	while (p->next)
	{
		if (p->data == cur_e)
		{
			next_e = p->next->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

Status ListInsert(LinkList &L, int i, ElemType e)
{
	int j = 0;
	LinkList s, p = L;
	while (p &&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p || j > i - 1)
		return ERROR;
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

Status ListDelete(LinkList &L, int i, ElemType &e)
{
	int j = 0;
	LinkList q, p = L;
	while (p->next&&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p->next || j > i - 1)
		return ERROR;
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return OK;
}

void ListTraverse(LinkList &L, void(*visit)(ElemType))
{
	LinkList p = L->next;
	while (p)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
}


主函数

 // algo2-3.cpp 实现算法2.11和2.12的程序
 #include"c1.h"


 void CreateList(LinkList &L,int n) // 算法2.11
 { // 逆位序(结点插在表头)输入n个元素的值,建立带表头结点的单链线性表L
   int i;
   LinkList p;
   L=(LinkList)malloc(sizeof(LNode)); // 生成头结点
   L->next=NULL; // 先建立一个带头结点的空单链表
   printf("请输入%d个数据\n",n);
   for(i=n;i>0;--i)
   { p=(LinkList)malloc(sizeof(LNode)); // 生成新结点
     scanf("%d",&p->data); // 给新结点输入元素值
     p->next=L->next; // 将新结点插在表头
     L->next=p; // 头结点指向新结点
   }
 }

 void CreateList1(LinkList &L,int n)
 { // 正位序(结点插在表尾)输入n个元素的值,建立带表头结点的单链线性表L
   int i;
   LinkList p,q;
   L=(LinkList)malloc(sizeof(LNode)); // 生成头结点
   L->next=NULL; // 先建立一个带头结点的空单链表
   q=L; // q指向空表的头结点(相当于尾结点)
   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; // q指向尾结点
   }
   p->next=NULL; // 最后一个结点的指针域为空
 }

 void MergeList(LinkList La,LinkList &Lb,LinkList &Lc) // 算法2.12
 { // 已知单链线性表La和Lb的元素按值非递减排列。
   // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。(销毁Lb,Lc即新的La)
   LinkList pa=La->next,pb=Lb->next,pc; // pa、pb分别指向La、Lb的首元结点(待比较结点)
   Lc=pc=La; // 用La的头结点作为Lc的头结点,pc指向La的头结点(Lc的尾结点)
   while(pa&&pb) // La和Lb中的元素都未比较完
     if(pa->data<=pb->data) // La的当前元素不大于Lb的当前元素
     { pc->next=pa; // 将pa所指结点归并到Lc中
       pc=pa; // pc指向表Lc的最后一个结点
       pa=pa->next; // 表La的下一个结点成为待比较结点
     }
     else // Lb的当前元素小于La的当前元素
     { pc->next=pb; // 将pb所指结点归并到Lc中
       pc=pb; // pc指向表Lc的最后一个结点
       pb=pb->next; // 表Lb的下一个结点成为待比较结点
     }
   pc->next=pa?pa:pb; // 插入剩余段
   free(Lb); // 释放Lb的头结点
   Lb=NULL; // Lb不再指向任何结点
 }

 void main()
 {
   int n=5;
   LinkList La,Lb,Lc;
   printf("按非递减顺序,");
   CreateList1(La,n); // 根据输入顺序,正位序建立线性表
   printf("La="); 
   ListTraverse(La,print); // 输出链表La的内容
   printf("按非递增顺序,");
   CreateList(Lb,n); // 根据输入顺序,逆位序建立线性表
   printf("Lb="); 
   ListTraverse(Lb,print); // 输出链表Lb的内容
   MergeList(La,Lb,Lc); // 按非递减顺序归并La和Lb,得到新表Lc
   printf("Lc="); 
   ListTraverse(Lc,print); // 输出链表Lc的内容
 }

2.2.3归并

头文件

 // c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
 typedef int ElemType;

 struct Sqlist
 {
	 ElemType *elem;
	 int length;
	 int listsize;
 };

 void InitList(Sqlist &L);
 void DestoryList(Sqlist &L);
 void ClearList(Sqlist &L);
 Status ListEmpty(Sqlist L);

 int ListLength(Sqlist L);

 Status GetElem(Sqlist L, int i, ElemType &e);

 int LocateElem(Sqlist L, ElemType e, Status(*compare)(ElemType, ElemType));
 //寻找前一个节点
 Status PriorElem(Sqlist L, ElemType cur_e, ElemType &pre_e);
 //寻找后一个结点
 Status NextElem(Sqlist L, ElemType cur_e, ElemType &next_e);

 Status ListInsert(Sqlist &L, int i, ElemType e);
 Status ListDelete(Sqlist &L, int i, ElemType &e);

 void ListTraverse(Sqlist &L, void(*visit)(ElemType&));


 Status equal(ElemType c1, ElemType c2);
 int comp(ElemType a, ElemType b);

 void print(ElemType c);
 void print1(ElemType &c);
 void print2(ElemType c);
#endif

bo2-1.cpp

#pragma once
#include"C1.H"
void InitList(Sqlist &L)
{
	L.elem = (ElemType*)malloc(sizeof(ElemType) * LIST_INIT_SIZE);
	if (!L.elem)
		exit(OVERFLOW);
	L.length = 0;
	L.listsize = LIST_INIT_SIZE;
}

void DestoryList(Sqlist &L)
{
	free(L.elem);
	L.elem = NULL;
	L.length = 0;
	L.listsize = 0;
}

void ClearList(Sqlist &L)
{
	L.length = 0;
}

Status ListEmpty(Sqlist L)
{
	if (L.length == 0)
		return TRUE;
	else
		return FALSE;
}

int ListLength(Sqlist L)
{
	return L.length;
}

Status GetElem(Sqlist L, int i, ElemType &e)
{
	if (i<1 || i>L.length)
		return ERROR;
	e = *(L.elem + i - 1);
	return OK;
}

int LocateElem(Sqlist L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 1;
	ElemType *p = L.elem;
	while (i <= L.length && !compare(*p++, e))
	++i;
	if (i <= L.length)
		return i;
	else
		return 0;
}
//寻找前一个节点
Status PriorElem(Sqlist L, ElemType cur_e, ElemType &pre_e)
{
	int i = 1;
	ElemType *p = L.elem + 1;
	while (i <= L.length &&*p != cur_e)
	{
		p++;
		i++;
	}

	if (i > L.length)
		return ERROR;
	else
	{
		pre_e = *--p;
		return OK;
	}
}
//寻找后一个结点
Status NextElem(Sqlist L, ElemType cur_e, ElemType &next_e)
{
	int i = 1;
	ElemType *p = L.elem;
	while (i < L.length && *p != cur_e)
	{
		p++;
		i++;
	}
	if (i == L.length)
		return ERROR;
	else
	{
		next_e = *++p;
		return OK;
	}
}

Status ListInsert(Sqlist &L, int i, ElemType e)
{
	ElemType *newbase, *p, *q;

	if (i < 1 || i >L.length + 1)
		return ERROR;
	if (L.length == L.listsize)
	{
		newbase = (ElemType*)realloc(L.elem, (L.listsize + LIST_INCREMENT) * sizeof(ElemType));
		if (!newbase)
			exit(OVERFLOW);
		L.elem = newbase;
		L.listsize += LIST_INCREMENT;
	}

	q = L.elem + i - 1;
	for (p = L.elem + L.length - 1; p >= q; --p)
		*(p + 1) = *p;
	*q = e;
	++L.length;
	return OK;
}

Status ListDelete(Sqlist &L, int i, ElemType &e)
{
	ElemType *p, *q;
	if (i<1 || i>L.length)
		return ERROR;
	p = L.elem + i - 1;
	e = *p;
	q = L.elem + L.length - 1;
	for (++p; p <= q; ++p)
		*(p - 1) = *p;
	L.length--;
	return OK;
}

void ListTraverse(Sqlist &L, void(*visit)(ElemType&))
{
	ElemType *p = L.elem;
	int i;
	for (i = 1; i <= L.length; i++)
		visit(*p++);
	printf("\n");
}

fun2-2.cpp

#include"C1.H"
Status equal(ElemType c1, ElemType c2)
{
	if (c1 == c2)
		return TRUE;
	else
		return FALSE;
}

int comp(ElemType a, ElemType b)
{
	if (a == b)
		return 0;
	else
		return (a - b) / abs(a - b);
}

void print(ElemType c)
{
	printf("%d", c);
}

void print1(ElemType &c)
{
	printf("%d ", c);
}

void print2(ElemType c)
{
	printf("%c", c);
}

主函数实现

#include"C1.H"

void MergeList(Sqlist La, Sqlist Lb, Sqlist &Lc)
{
	ElemType *pa, *pa_last, *pb, *pb_last, *pc;
	pa = La.elem;
	pb = Lb.elem;
	Lc.length = Lc.listsize = La.length + Lb.length;
	pc = Lc.elem = (ElemType*)malloc(sizeof(ElemType) * Lc.length);
	if (!Lc.elem)
		exit(OVERFLOW);
	pa_last = pa + La.length - 1;
	pb_last = pb + Lb.length - 1;
	while (pa <= pa_last&&pb <= pb_last)
	{
		if (*pa <= *pb)
			*pc++ = *pa++;
		else
			*pc++ = *pb++;
	}
	while (pa <= pa_last)
		*pc++ = *pa++;
	while (pb <= pb_last)
		*pc++ = *pb++;
}

int main() {
	Sqlist La, Lb, Lc;
	int j;
	InitList(La);
	InitList(Lb);
	for (j = 1; j <= 5; j++)
		ListInsert(La, j, j);
	ListTraverse(La, print1);
	for (j = 1; j <= 5; j++)
		ListInsert(Lb, j, 2*j);
	ListTraverse(Lb, print1);

	MergeList(La, Lb, Lc);
	ListTraverse(Lc, print1);
	return 0;
}

2.3.1线性表的链式表示和实现

头文件

 // c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
 typedef int ElemType;

 struct LNode
 {
	 ElemType data;
	 LNode *next;
 };
 typedef LNode *LinkList;

 void InitList(LinkList &L);
 void DestoryList(LinkList &L);
 void ClearList(LinkList &L);
 Status ListEmpty(LinkList L);

 int ListLength(LinkList L);

 Status GetElem(LinkList L, int i, ElemType &e);

 int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
 //寻找前一个节点
 Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
 //寻找后一个结点
 Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);

 Status ListInsert(LinkList &L, int i, ElemType e);
 Status ListDelete(LinkList &L, int i, ElemType &e);

 void ListTraverse(LinkList &L, void(*visit)(ElemType));


 Status equal(ElemType c1, ElemType c2);

 int comp(ElemType a, ElemType b);

 void print(ElemType c);

 void print1(ElemType c);

 void print2(ElemType c);
#endif

实现函数:

#include"C1.H"

void InitList(LinkList &L)
{
	L = (LNode*)malloc(sizeof(LNode));
	if (!L)
		exit(OVERFLOW);
	L->next = NULL;
}

void DestoryList(LinkList &L)
{
	LinkList q;
	while (L)
	{
		q = L->next;
		free(L);
		L = q;
	}

}
void ClearList(LinkList &L)
{
	LinkList p = L->next;
	L->next = NULL;
	DestoryList(p);
}

Status ListEmpty(LinkList L)
{
	if (L->next)
		return FALSE;
	else
		return TRUE;
}

int ListLength(LinkList L)
{
	int i = 0;
	LinkList q = L->next;
	while (q)
	{
		i++;
		q = q->next;
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType &e)
{
	int j = 1;
	LinkList q = L->next;
	while (q && j < i)
	{
		j++;
		q = q->next;
	}
	if (!q || j > i)
		return ERROR;
	e = q->data;
	return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	LinkList p = L->next;
	while (p)
	{
		i++;
		if (compare(p->data, e))
			return i;
		p = p->next;
	}
	return 0;
}
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	LinkList q, p = L->next;
	while (p->next)
	{
		q = p->next;
		if (q->data == cur_e)
		{
			pre_e = p->data;
			return OK;
		}
		p = q;
	}
	return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	LinkList p = L->next;
	while (p->next)
	{
		if (p->data == cur_e)
		{
			next_e = p->next->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

Status ListInsert(LinkList &L, int i, ElemType e)
{
	int j = 0;
	LinkList s, p = L;
	while (p &&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p || j > i - 1)
		return ERROR;
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

Status ListDelete(LinkList &L, int i, ElemType &e)
{
	int j = 0;
	LinkList q, p = L;
	while (p->next&&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p->next || j > i - 1)
		return ERROR;
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return OK;
}

void ListTraverse(LinkList &L, void(*visit)(ElemType))
{
	LinkList p = L->next;
	while (p)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
}

void print(ElemType c)
{
	printf("%d", c);
}


主函数

#include "C1.H"

int main() 
{
	LinkList L;
	ElemType e, e0;
	Status i;
	int j, k;
	InitList(L);
	for (j = 1; j <= 5; j++)
		i = ListInsert(L, 1, j);
	printf("在L的表头一次插入1-5后,L = ");
	ListTraverse(L, print);

	i = ListEmpty(L);
	printf("L是否空?i = %d(1是0否),表L的长度 = %d\n", i, ListLength(L));
	ClearList(L);
	printf("清空L之后,L = ");
	ListTraverse(L, print);
	i = ListEmpty(L);
	printf("L是否空?i = %d(1是0否),表L的长度 = %d\n", i, ListLength(L));
	for (j = 1; j <= 10; j++)
		i = ListInsert(L, j, j);


	for (j = 1; j <= 2; j++)
	{
		GetElem(L, j, e0);
		i = PriorElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无前驱\n", e0);
		else
			printf("元素%d的前驱为%d\n", e0, e);
	}

	for (j = ListLength(L) - 1; j <= ListLength(L); j++)
	{
		GetElem(L, j, e0);
		i = NextElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无后继\n", e0);
		else
			printf("元素%d的后继为%d\n", e0, e);
	}
	k = ListLength(L);
	for (j = k + 1; j >= k; j--)
	{
		i = ListDelete(L, j, e);
		if (i == ERROR)
			printf("%d个元素删除失败\n", j);
		else
			printf("%d个元素删除成功,值为%d\n", j, e);
	}

	printf("依次输出L的元素:");
	ListTraverse(L, print);
	DestoryList(L);
	printf("销毁后,L = %u", L);
}

2.3.2 不设头节点

头文件

// c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



#include<string.h> // 字符串函数头文件
#include<ctype.h> // 字符函数头文件
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
#include<stdlib.h> // atoi(),exit()
#include<io.h> // eof()
#include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
#include<sys/timeb.h> // ftime()
#include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
// 函数结果状态代码。在教科书第10页
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
// #define INFEASIBLE -1 没使用
// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
typedef int ElemType;

struct LNode
{
	ElemType data;
	LNode *next;
};
typedef LNode *LinkList;

void InitList(LinkList &L);
void DestoryList(LinkList &L);
void ClearList(LinkList &L);
Status ListEmpty(LinkList L);

int ListLength(LinkList L);

Status GetElem(LinkList L, int i, ElemType &e);

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
//寻找前一个节点
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
//寻找后一个结点
Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);

Status ListInsert(LinkList &L, int i, ElemType e);
Status ListDelete(LinkList &L, int i, ElemType &e);

void ListTraverse(LinkList &L, void(*visit)(ElemType));


Status equal(ElemType c1, ElemType c2);
int comp(ElemType a, ElemType b);

void print(ElemType c);

void Union(LinkList &La, LinkList Lb);
void MergeList(LinkList La, LinkList Lb, LinkList &Lc);
#endif
// bo2-3.cpp 不设头结点的单链表(存储结构由c2-2.h定义)的部分基本操作(9个)
#include"C1.h"
#define DestroyList ClearList // DestroyList()和ClearList()的操作是一样的
void InitList(LinkList &L)
{ // 操作结果:构造一个空的线性表L
	L = NULL; // 指针为空
}

void ClearList(LinkList &L)
{ // 初始条件:线性表L已存在。操作结果:将L重置为空表
	LinkList p;
	while (L) // L不空
	{
		p = L; // p指向首元结点
		L = L->next; // L指向第2个结点(新首元结点)
		free(p); // 释放首元结点
	}
}

Status ListEmpty(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
	if (L)
		return FALSE;
	else
		return TRUE;
}

int ListLength(LinkList L)
{ // 初始条件:线性表L已存在。操作结果:返回L中数据元素的个数
	int i = 0; // 计数器初值为0
	LinkList p = L; // p指向第1个结点
	while (p) // p指向结点(未到表尾)
	{
		i++; // 计数器+1
		p = p->next; // p指向下一个结点
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType &e)
{ // L为不设头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,
  // 否则返回ERROR
	int j = 1; // 计数器初值为1
	LinkList p = L; // p指向第1个结点
	if (i<1) // i值不合法
		return ERROR;
	while (j<i&&p) // 未到第i个元素,也未到表尾
	{
		j++; // 计数器+1
		p = p->next; // p指向下一个结点
	}
	if (j == i&&p) // 存在第i个元素
	{
		e = p->data; // 取第i个元素的值赋给e
		return OK; // 成功返回OK
	}
	return ERROR; // 不存在第i个元素,失败返回ERROR
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{ // 初始条件:线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
  // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
  //           若这样的数据元素不存在,则返回值为0
	int i = 0; // 计数器初值为0
	LinkList p = L; // p指向第1个结点
	while (p) // 未到表尾
	{
		i++; // 计数器+1
		if (compare(p->data, e)) // 找到这样的数据元素
			return i; // 返回其位序
		p = p->next; // p指向下一个结点
	}
	return 0; // 满足关系的数据元素不存在
}

Status ListInsert(LinkList &L, int i, ElemType e)
{ // 在不设头结点的单链线性表L中第i个位置之前插入元素e
	int j = 1; // 计数器初值为1
	LinkList s, p = L; // p指向第1个结点
	if (i<1) // i值不合法
		return ERROR;
	s = (LinkList)malloc(sizeof(LNode)); // 生成新结点,以下将其插入L中
	s->data = e; // 给s的data域赋值e
	if (i == 1) // 插在表头
	{
		s->next = L; // 新结点指向原第1个结点
		L = s; // L指向新结点(改变L)
	}
	else
	{ // 插在表的其余处
		while (p&&j<i - 1) // 寻找第i-1个结点
		{
			j++; // 计数器+1
			p = p->next; // p指向下一个结点
		}
		if (!p) // i大于表长+1
			return ERROR; // 插入失败
		s->next = p->next; // 新结点指向原第i个结点
		p->next = s; // 原第i-1个结点指向新结点
	}
	return OK; // 插入成功
}

Status ListDelete(LinkList &L, int i, ElemType &e)
{ // 在不设头结点的单链线性表L中,删除第i个元素,并由e返回其值
	int j = 1; // 计数器初值为1
	LinkList q, p = L; // p指向第1个结点
	if (!L) // 表L空
		return ERROR; // 删除失败
	else if (i == 1) // 删除第1个结点
	{
		L = p->next; // L由第2个结点开始(改变L)
		e = p->data; // 将待删结点的值赋给e
		free(p); // 删除并释放第1个结点
	}
	else
	{
		while (p->next&&j<i - 1) // 寻找第i个结点,并令p指向其前驱
		{
			j++; // 计数器+1
			p = p->next; // p指向下一个结点
		}
		if (!p->next || j>i - 1) // 删除位置不合理
			return ERROR; // 删除失败
		q = p->next; // q指向待删除结点
		p->next = q->next; // 待删结点的前驱指向待删结点的后继
		e = q->data; // 将待删结点的值赋给e
		free(q); // 释放待删结点
	}
	return OK; // 删除成功
}

void ListTraverse(LinkList L, void(*vi)(ElemType))
{ // 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi()
	LinkList p = L; // p指向第1个结点
	while (p) // p所指结点存在
	{
		vi(p->data); // 对p所指结点调用函数vi()
		p = p->next; // p指向下一个结点
	}
	printf("\n");
}

// bo2-4.cpp 不设头结点的单链表(存储结构由c2-2.h定义)的部分基本操作(2个)
#include"C1.h"

Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{ // 初始条件:线性表L已存在
  // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,返回OK;
  //           否则操作失败,pre_e无定义,返回ERROR
	LinkList q, p = L; // p指向第1个结点
	while (p->next) // p所指结点有后继
	{
		q = p->next; // q指向p的后继
		if (q->data == cur_e) // p的后继为cur_e
		{
			pre_e = p->data; // 将p所指元素的值赋给pre_e
			return OK; // 成功返回OK
		}
		p = q; // p的后继不为cur_e,p向后移
	}
	return ERROR; // 操作失败,返回ERROR
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{ // 初始条件:线性表L已存在
  // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,返回OK,
  //           否则操作失败,next_e无定义,返回ERROR
	LinkList p = L; // p指向第1个结点
	while (p->next) // p所指结点有后继
	{
		if (p->data == cur_e) // p所指结点的值为cur_e
		{
			next_e = p->next->data; // 将p所指结点的后继结点的值赋给next_e
			return OK; // 成功返回OK
		}
		p = p->next; // p指向下一个结点
	}
	return ERROR; // 操作失败,返回ERROR
}

// func2-2.cpp 几个常用的函数
#include"C1.H"
Status equal(ElemType c1, ElemType c2)
{ // 判断是否相等的函数
	if (c1 == c2)
		return TRUE;
	else
		return FALSE;
}

int comp(ElemType a, ElemType b)
{ // 根据a<、=或>b,分别返回-1、0或1
	if (a == b)
		return 0;
	else
		return (a - b) / abs(a - b);
}

void print(ElemType c)
{ // 以十进制整型的格式输出元素的值
	printf("%d ", c);
}

void print1(ElemType &c)
{ // 以十进制整型的格式输出元素的值(设c为引用类型)
	printf("%d ", c);
}

void print2(ElemType c)
{ // 以字符型的格式输出元素的值
	printf("%c ", c);
}

#include "C1.H"

int main()
{
	LinkList La, Lb, Lc;
	int j, b[7] = { 2,6,8,9,11,15,20 };
	InitList(La);
	for (j = 1; j <= 5; j++)
		ListInsert(La, j, j);
	ListTraverse(La, print);

	InitList(Lb);
	for (j = 1; j <= 5; j++)
		ListInsert(Lb, j, 2 * j);
	ListTraverse(Lb, print);

	Union(La, Lb);
	ListTraverse(La, print);

	ClearList(Lb);

	for (j = 1; j <= 7; j++)
		ListInsert(Lb, j, b[j - 1]);

	ListTraverse(Lb, print);

	MergeList(La, Lb, Lc);
	ListTraverse(Lc, print);
}

2.3.3 静态链

 // c1.h (文件名)
 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到

#include "C1.H"
#define MAX_SIZE 100
#define N 6

typedef char ElemType[N];

typedef struct {
	ElemType data;
	int cur;
}component,SLinkList[MAX_SIZE];

int main()
{
	SLinkList s = { {"",1},{"ZHAO",2},{"QIAN",3},{"SUN",4},{"LI",5} ,{"ZHOU",6}, {"WU",7}, {"ZHENG",8}, {"WANG",0} };
	int i = s[0].cur;
	while (i)
	{
		printf("%s ", s[i].data);
		i = s[i].cur;
	}
	printf("\n");

	s[4].cur = 9;
	s[9].cur = 5;
	strcpy(s[9].data, "SHI");
	s[6].cur = 8;
	i = s[0].cur;
	while (i)
	{
		printf("%s ", s[i].data);
		i = s[i].cur;
	}
	printf("\n");
	return 0;
}

2.3.4链表归并

 // c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
 typedef int ElemType;

 struct LNode
 {
	 ElemType data;
	 LNode *next;
 };
 typedef LNode *LinkList;

 void InitList(LinkList &L);
 void DestoryList(LinkList &L);
 void ClearList(LinkList &L);
 Status ListEmpty(LinkList L);

 int ListLength(LinkList L);

 Status GetElem(LinkList L, int i, ElemType &e);

 int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
 //寻找前一个节点
 Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
 //寻找后一个结点
 Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);

 Status ListInsert(LinkList &L, int i, ElemType e);
 Status ListDelete(LinkList &L, int i, ElemType &e);

 void ListTraverse(LinkList &L, void(*visit)(ElemType));


 Status equal(ElemType c1, ElemType c2);
 int comp(ElemType a, ElemType b);

 void print(ElemType c);

 void Union(LinkList &La, LinkList Lb);
 void MergeList(LinkList La, LinkList Lb, LinkList &Lc);
#endif
#include"C1.H"

void InitList(LinkList &L)
{
	L = (LNode*)malloc(sizeof(LNode));
	if (!L)
		exit(OVERFLOW);
	L->next = NULL;
}

void DestoryList(LinkList &L)
{
	LinkList q;
	while (L)
	{
		q = L->next;
		free(L);
		L = q;
	}

}
void ClearList(LinkList &L)
{
	LinkList p = L->next;
	L->next = NULL;
	DestoryList(p);
}

Status ListEmpty(LinkList L)
{
	if (L->next)
		return FALSE;
	else
		return TRUE;
}

int ListLength(LinkList L)
{
	int i = 0;
	LinkList q = L->next;
	while (q)
	{
		i++;
		q = q->next;
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType &e)
{
	int j = 1;
	LinkList q = L->next;
	while (q && j < i)
	{
		j++;
		q = q->next;
	}
	if (!q || j > i)
		return ERROR;
	e = q->data;
	return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	LinkList p = L->next;
	while (p)
	{
		i++;
		if (compare(p->data, e))
			return i;
		p = p->next;
	}
	return 0;
}
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	LinkList q, p = L->next;
	while (p->next)
	{
		q = p->next;
		if (q->data == cur_e)
		{
			pre_e = p->data;
			return OK;
		}
		p = q;
	}
	return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	LinkList p = L->next;
	while (p->next)
	{
		if (p->data == cur_e)
		{
			next_e = p->next->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

Status ListInsert(LinkList &L, int i, ElemType e)
{
	int j = 0;
	LinkList s, p = L;
	while (p &&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p || j > i - 1)
		return ERROR;
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

Status ListDelete(LinkList &L, int i, ElemType &e)
{
	int j = 0;
	LinkList q, p = L;
	while (p->next&&j < i - 1)
	{
		j++;
		p = p->next;
	}
	if (!p->next || j > i - 1)
		return ERROR;
	q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);
	return OK;
}

void ListTraverse(LinkList &L, void(*visit)(ElemType))
{
	LinkList p = L->next;
	while (p)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
}


// func2-2.cpp 几个常用的函数
#include"C1.H"
Status equal(ElemType c1, ElemType c2)
{ // 判断是否相等的函数
	if (c1 == c2)
		return TRUE;
	else
		return FALSE;
}

int comp(ElemType a, ElemType b)
{ // 根据a<、=或>b,分别返回-1、0或1
	if (a == b)
		return 0;
	else
		return (a - b) / abs(a - b);
}

void print(ElemType c)
{ // 以十进制整型的格式输出元素的值
	printf("%d ", c);
}

void print1(ElemType &c)
{ // 以十进制整型的格式输出元素的值(设c为引用类型)
	printf("%d ", c);
}

void print2(ElemType c)
{ // 以字符型的格式输出元素的值
	printf("%c ", c);
}

#include "C1.H"

void Union(LinkList &La, LinkList Lb)
{
	ElemType e;
	int La_len, Lb_len;
	int i;
	La_len = ListLength(La); // 求线性表La的长度
	Lb_len = ListLength(Lb); // 求线性表Lb的长度
	for (i = 1; i <= Lb_len; i++) // 从表Lb的第1个元素到最后1个元素
	{
		GetElem(Lb, i, e); // 取表Lb中第i个数据元素的值赋给e
		if (!LocateElem(La, e, equal)) // 表La中不存在和e相同的元素
			ListInsert(La, ++La_len, e); // 在表La的最后插入元素e
	}
}

void MergeList(LinkList La, LinkList Lb, LinkList &Lc)
{
	int i = 1, j = 1, k = 0;
	int La_len, Lb_len;
	ElemType ai, bj;
	InitList(Lc);
	La_len = ListLength(La);
	Lb_len = ListLength(Lb);
	while (i <= La_len&&j <= Lb_len)
	{
		GetElem(La, i, ai);
		GetElem(Lb, j, bj);
		if (ai <= bj)
		{
			ListInsert(Lc, ++k, ai);
			++i;
		}
		else
		{
			ListInsert(Lc, ++k, bj);
			++j;
		}
	}

	while (i <= La_len)
	{
		GetElem(La, i++, ai);
		ListInsert(Lc, ++k, ai);
	}

	while (j <= Lb_len)
	{
		GetElem(La, j++, bj);
		ListInsert(Lc, ++k, bj);
	}
}
#include "C1.H"

int main()
{
	LinkList La, Lb, Lc;
	int j, b[7] = { 2,6,8,9,11,15,20 };
	InitList(La);
	for (j = 1; j <= 5; j++)
		ListInsert(La, j, j);
	ListTraverse(La, print);

	InitList(Lb);
	for (j = 1; j <= 5; j++)
		ListInsert(Lb, j, 2*j);
	ListTraverse(Lb, print);
	
	Union(La, Lb);
	ListTraverse(La,print);
	
	ClearList(Lb);
	
	for (j = 1; j <= 7; j++)
		ListInsert(Lb, j, b[j - 1]);
	
	ListTraverse(Lb, print);
	
	MergeList(La, Lb, Lc);
	ListTraverse(Lc, print);
}

2.3.5循环链表

 // c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
 typedef int ElemType;

 struct LNode
 {
	 ElemType data;
	 LNode *next;
 };
 typedef LNode *LinkList;

 void InitList(LinkList &L);
 void DestoryList(LinkList &L);
 void ClearList(LinkList &L);
 Status ListEmpty(LinkList L);

 int ListLength(LinkList L);

 Status GetElem(LinkList L, int i, ElemType &e);

 int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
 //寻找前一个节点
 Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
 //寻找后一个结点
 Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);

 Status ListInsert(LinkList &L, int i, ElemType e);
 Status ListDelete(LinkList &L, int i, ElemType &e);

 void ListTraverse(LinkList &L, void(*visit)(ElemType));


 Status equal(ElemType c1, ElemType c2);

 int comp(ElemType a, ElemType b);

 void print(ElemType c);

 void print1(ElemType c);

 void print2(ElemType c);
#endif
#include"C1.H"

void InitList(LinkList &L)
{
	L = (LNode*)malloc(sizeof(LNode));
	if (!L)
		exit(OVERFLOW);
	L->next = L;
}

void ClearList(LinkList &L)
{
	LinkList p,q;
	L = L->next;
	p = L->next;
	while (p != L)
	{
		q = p->next;
		free(p);
		p = q;
	}
	L->next = L;
}

void DestoryList(LinkList &L)
{
	ClearList(L);
	free(L);
	L = NULL;
}

Status ListEmpty(LinkList L)
{
	if (L->next == L)
		return TRUE;
	else
		return FALSE;
}

int ListLength(LinkList L)
{
	int i = 0;
	LinkList q = L->next;
	while (q != L)
	{
		i++;
		q = q->next;
	}
	return i;
}

Status GetElem(LinkList L, int i, ElemType &e)
{
	int j = 1;
	LinkList p = L->next->next;
	if (i <= 0 || i > ListLength(L))
		return ERROR;
	while (j<i)
	{
		j++;
		p = p->next;
	}

	e = p->data;
	return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	LinkList p = L->next ->next;
	while (p!=L->next)
	{
		i++;
		if (compare(p->data, e))
			return i;
		p = p->next;
	}
	return 0;
}
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e)
{
	LinkList q, p = L->next->next;
	q = p->next;
	while (q != L->next)
	{
		if (q->data == cur_e)
		{
			pre_e = p->data;
			return OK;
		}
		p = q;
		q = q->next;
	}
	return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e)
{
	LinkList p = L->next->next;
	while (p!=L)
	{
		if (p->data == cur_e)
		{
			next_e = p->next->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

Status ListInsert(LinkList &L, int i, ElemType e)
{
	int j = 0;
	LinkList s, p = L->next;
	if (i <= 0 || i > ListLength(L) +1)
		return ERROR;
	while (j < i - 1)
	{
		j++;
		p = p->next;
	}
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	if (p == L)
		L = s;
	return OK;
}

Status ListDelete(LinkList &L, int i, ElemType &e)
{
	int j = 0;
	LinkList q, p = L->next;
	if (i <= 0 || i > ListLength(L))
		return ERROR;
	while (j < i - 1)
	{
		j++;
		p = p->next;
	}
	q = p->next;
	p->next = q->next;
	e = q->data;
	if (L == q)
		L = p;
	free(q);
	return OK;
}

void ListTraverse(LinkList &L, void(*visit)(ElemType))
{
	LinkList p = L->next->next;
	while (p!=L->next)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
}

void print(ElemType c)
{
	printf("%d", c);
}


#include "C1.H"

int main() 
{
	LinkList L;
	ElemType e, e0;
	Status i;
	int j, k;
	InitList(L);
	for (j = 1; j <= 5; j++)
		i = ListInsert(L, 1, j);
	printf("在L的表头一次插入1-5后,L = ");
	ListTraverse(L, print);

	i = ListEmpty(L);
	printf("L是否空?i = %d(1是0否),表L的长度 = %d\n", i, ListLength(L));
	ClearList(L);
	printf("清空L之后,L = ");
	ListTraverse(L, print);
	i = ListEmpty(L);
	printf("L是否空?i = %d(1是0否),表L的长度 = %d\n", i, ListLength(L));
	for (j = 1; j <= 10; j++)
		i = ListInsert(L, j, j);

	ListTraverse(L, print);
	for (j = 1; j <= 2; j++)
	{
		GetElem(L, j, e0);
		i = PriorElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无前驱\n", e0);
		else
			printf("元素%d的前驱为%d\n", e0, e);
	}

	for (j = ListLength(L) - 1; j <= ListLength(L); j++)
	{
		GetElem(L, j, e0);
		i = NextElem(L, e0, e);
		if (i == ERROR)
			printf("元素%d无后继\n", e0);
		else
			printf("元素%d的后继为%d\n", e0, e);
	}
	k = ListLength(L);
	for (j = k + 1; j >= k; j--)
	{
		i = ListDelete(L, j, e);
		if (i == ERROR)
			printf("%d个元素删除失败\n", j);
		else
			printf("%d个元素删除成功,值为%d\n", j, e);
	}

	printf("依次输出L的元素:");
	ListTraverse(L, print);
	//DestoryList(L);
	//printf("销毁后,L = %u", L);
}

2.3.6静态链表的操做

 // c1.h (文件名)
 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到

#include "C1.H"
#define MAX_SIZE 100
#define N 6

typedef char ElemType;

typedef struct {
	ElemType data;
	int cur;
}component, SLinkList[MAX_SIZE];

#define DestroyList ClearList

int Malloc(SLinkList space)
{
	int i = space[0].cur;
	if (i)
		space[0].cur = space[i].cur;
	return i;
}

void Free(SLinkList space, int k)
{
	space[k].cur = space[0].cur;
	space[0].cur = k;
}

void InitList(SLinkList L)
{
	int i;
	L[MAX_SIZE - 1].cur = 0;
	for (i = 0; i < MAX_SIZE - 2; i++)
		L[i].cur = i + 1;
	L[MAX_SIZE - 2].cur = 0;
}


void ClearList(SLinkList L)
{
	int j, k, i = L[MAX_SIZE - 1].cur;
	L[MAX_SIZE - 1].cur = 0;
	k = L[0].cur;
	L[0].cur = i;
	while (i)
	{
		j = i;
		i = L[i].cur;
	}
	L[j].cur = k;
}

Status ListEmpty(SLinkList L)
{
	if (L[MAX_SIZE - 1].cur == 0)
		return TRUE;
	else
		return FALSE;
}

int ListLength(SLinkList L)
{
	int j = 0, i = L[MAX_SIZE - 1].cur;
	while (i)
	{
		i = L[i].cur;
		j++;
	}
	return j;
}

Status GetElem(SLinkList L, int i, ElemType &e)
{
	int m, k = MAX_SIZE - 1;
	if (i<1 || i>ListLength(L))
		return ERROR;
	for (m = 1; m <= i; ++m)
		k = L[k].cur;
	e = L[k].data;
	return OK;
}

int LocateElem(SLinkList L, ElemType e)
{
	int i = L[MAX_SIZE - 1].cur;
	while (i&&L[i].data != e)
		i = L[i].cur;
	return i;
}

Status PriorElem(SLinkList L, ElemType cur_e, ElemType &pre_e)
{
	int j, i = L[MAX_SIZE - 1].cur;
	do {
		j = i;
		i = L[i].cur;
	}while(i&&cur_e != L[i].data);

	if (i)
	{
		pre_e = L[j].data;
		return OK;
	}

	return ERROR;
}

Status NextElem(SLinkList L, ElemType cur_e, ElemType &next_e)
{
	int j, i = LocateElem(L, cur_e);
	if (i)
	{
		j = L[i].cur;
		if (j)
		{
			next_e = L[j].data;
			return OK;
		}
	}
	return ERROR;
}

Status ListInsert(SLinkList L, int i, ElemType e)
{
	int m, j, k = MAX_SIZE - 1;
	if (i<1 || i>ListLength(L) + 1)
		return ERROR;
	j = Malloc(L);
	if (j)
	{
		L[j].data = e;
		for (m = 1; m < i; m++)
			k = L[k].cur;
		L[j].cur = L[k].cur;
		L[k].cur = j;
		return OK;
	}
	return ERROR;
}

Status ListDelete(SLinkList L, int i, ElemType &e)
{
	int j, k = MAX_SIZE - 1;
	if (i<1 || i>ListLength(L))
		return ERROR;
	for (j = 1; j < i; j++)
		k = L[k].cur;
	j = L[k].cur;
	L[k].cur = L[j].cur;
	e = L[j].data;
	Free(L, j);
	return OK;
}

void ListTraverse(SLinkList L, void(*visit)(ElemType))
{
	int i = L[MAX_SIZE - 1].cur;
	while (i)
	{
		visit(L[i].data);
		i = L[i].cur;
	}
	printf("\n");
}


2.7双向链表

 // c1.h (文件名)
#ifndef C1_H
#define C1_H

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2



 #include<string.h> // 字符串函数头文件
 #include<ctype.h> // 字符函数头文件
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
 #include<stdlib.h> // atoi(),exit()
 #include<io.h> // eof()
 #include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等
 #include<sys/timeb.h> // ftime()
 #include<stdarg.h> // 提供宏va_start,va_arg和va_end,用于存取变长参数表
 // 函数结果状态代码。在教科书第10页
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 // #define INFEASIBLE -1 没使用
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
 typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE,第7、8章用到
 typedef int ElemType;

 typedef struct DuLNode
 {
	 ElemType data;
	 DuLNode *next,*prior;
 }DuLNode,*DuLinkList;


 void InitList(DuLinkList &L);
 void DestoryList(DuLinkList &L);
 void ClearList(DuLinkList &L);
 Status ListEmpty(DuLinkList L);

 int ListLength(DuLinkList L);

 Status GetElem(DuLinkList L, int i, ElemType &e);

 int LocateElem(DuLinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
 //寻找前一个节点
 Status PriorElem(DuLinkList L, ElemType cur_e, ElemType &pre_e);
 //寻找后一个结点
 Status NextElem(DuLinkList L, ElemType cur_e, ElemType &next_e);

 Status ListInsert(DuLinkList &L, int i, ElemType e);
 Status ListDelete(DuLinkList &L, int i, ElemType &e);

 void ListTraverse(DuLinkList &L, void(*visit)(ElemType));
 void ListTraverseBack(DuLinkList &L, void(*visit)(ElemType));


 DuLinkList GetElemP(DuLinkList L, int i);

 Status equal(ElemType c1, ElemType c2);

 int comp(ElemType a, ElemType b);

 void print(ElemType c);

 void print1(ElemType c);

 void print2(ElemType c);
#endif
#include"C1.H"

void InitList(DuLinkList &L)
{
	L = (DuLNode*)malloc(sizeof(DuLNode));
	if (!L)
		exit(OVERFLOW);
	else
	{
		L->next = L->prior = L;
	}
}

void ClearList(DuLinkList &L)
{
	DuLinkList p = L->next;
	while (p != L)
	{
		p = p->next;
		free(p->prior);
	}
	L->next = L->prior = L;
}

void DestoryList(DuLinkList &L)
{
	ClearList(L);
	free(L);
	L = NULL;
}

Status ListEmpty(DuLinkList L)
{
	if (L->next == L &&L->prior == L)
		return TRUE;
	else
		return FALSE;
}

int ListLength(DuLinkList L)
{
	int i = 0;
	DuLinkList q = L->next;
	while (q != L)
	{
		i++;
		q = q->next;
	}
	return i;
}

Status GetElem(DuLinkList L, int i, ElemType &e)
{
	int j = 1;
	DuLinkList p = L->next;
	while (p != L && j<i)
	{
		j++;
		p = p->next;
	}
	if (p == L || j > i)
		return ERROR;
	e = p->data;
	return OK;
}

int LocateElem(DuLinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	DuLinkList p = L->next;
	while (p != L)
	{
		i++;
		if (compare(p->data, e))
			return i;
		p = p->next;
	}
	return 0;
}
Status PriorElem(DuLinkList L, ElemType cur_e, ElemType &pre_e)
{
	DuLinkList p = L->next->next;
	while (p != L)
	{
		if (p->data == cur_e)
		{
			pre_e = p->prior->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

Status NextElem(DuLinkList L, ElemType cur_e, ElemType &next_e)
{
	DuLinkList p = L->next->next;
	while (p != L)
	{
		if (p->prior->data == cur_e)
		{
			next_e = p->data;
			return OK;
		}
		p = p->next;
	}
	return ERROR;
}

DuLinkList GetElemP(DuLinkList L, int i)
{
	int j;
	DuLinkList p = L;
	if (i < 0 || i>ListLength(L))
		return ERROR;
	for (j = 1; j <= i; j++)
		p = p->next;
	return p;
}


Status ListInsert(DuLinkList &L, int i, ElemType e)
{
	int j = 0;
	DuLinkList s, p = L->next;
	if (i <= 0 || i > ListLength(L) + 1)
		return ERROR;	
	p = GetElemP(L, i - 1);
	s = (DuLinkList)malloc(sizeof(DuLNode));
	s->data = e;
	s->next = p->next;
	s->prior = p;
	p->next->prior = s;
	p->next = s;
	return OK;
}

Status ListDelete(DuLinkList &L, int i, ElemType &e)
{
	int j = 0;
	DuLinkList p;
	if (i <= 1)
		return ERROR;
	p = GetElemP(L, i);
	if (!p)
		return ERROR;
	e = p->data;
	p->prior->next = p->next;
	p->next->prior = p->prior;
	free(p);
	return OK;
}

void ListTraverse(DuLinkList &L, void(*visit)(ElemType))
{
	DuLinkList p = L->next;
	while (p != L)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
}

void ListTraverseBack(DuLinkList &L, void(*visit)(ElemType))
{
	DuLinkList p = L->prior;
	while (p != L)
	{
		visit(p->data);
		p = p->prior;
	}
	printf("\n");
}


void print(ElemType c)
{
	printf("%d", c);
}

Status equal(ElemType c1, ElemType c2)
{
	if (c1 == c2)
		return TRUE;
	else
		return FALSE;
}



// main2-6.cpp 检验bo2-7.cpp的主程序
#include"c1.h"

void main()
{
	DuLinkList L;
	int i, n = 4;
	Status j;
	ElemType e;
	InitList(L); // 初始化线性表L
	for (i = 1; i <= 5; i++) // 依次插入1~5
		ListInsert(L, i, i); // 在第i个结点之前插入i
	printf("逆序输出链表:");
	ListTraverseBack(L, print); // 逆序输出
	j = GetElem(L, 2, e); // 将链表的第2个元素赋值给e
	if (j)
		printf("链表的第2个元素值为%d\n", e);
	else
		printf("不存在第2个元素\n");
	i = LocateElem(L, n, equal);
	if (i)
		printf("等于%d的元素是第%d个\n", n, i);
	else
		printf("没有等于%d的元素\n", n);
	j = PriorElem(L, n, e);
	if (j)
		printf("%d的前驱是%d,", n, e);
	else
		printf("不存在%d的前驱\n", n);
	j = NextElem(L, n, e);
	if (j)
		printf("%d的后继是%d\n", n, e);
	else
		printf("不存在%d的后继\n", n);
	ListDelete(L, 2, e); // 删除并释放第2个结点
	printf("删除第2个结点,值为%d,其余结点为 ", e);
	ListTraverse(L, print); // 正序输出
	printf("链表的元素个数为%d,", ListLength(L));
	printf("链表是否空?%d(1:是 0:否)\n", ListEmpty(L));
	ClearList(L); // 清空链表
	printf("清空后,链表是否空?%d(1:是 0:否)\n", ListEmpty(L));
	DestoryList(L);
}

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值