💡 【教材】 ▲02 线性表

This commit is contained in:
康建伟
2018-01-03 19:03:58 +08:00
parent d1474f014a
commit 3384a3cebf
42 changed files with 3986 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
/***************************************
* *
* 文件夹: ▲02 线性表\01 SequenceList *
* *
* 内 容: 单链表顺序结构相关函数测试 *
* *
***************************************/
#include <stdio.h>
#include "SequenceList.c" //**▲02 线性表**//
/* 测试调用的函数原型 */
Status CmpGreater(LElemType_Sq e, LElemType_Sq data);
//若data>e返回TRUE否则返回FALSE
void PrintElem(LElemType_Sq e);
//测试函数,打印整型
int main(int argc, char **argv)
{
SqList L;
int i;
LElemType_Sq e;
printf("▼1\n▲函数 InitList_Sq 测试...\n"); //1.函数InitList_Sq测试
{
printf("初始化顺序表 L ...\n");
InitList_Sq(&L);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 ListEmpty_Sq 测试...\n"); //4.函数ListEmpty_Sq测试
{
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼10\n▲函数 ListInsert_Sq 测试...\n"); //10.函数ListInsert_Sq测试
{
for(i=1; i<=6; i++)
{
printf("作为示范,在 L 第 %d 个位置插入 \"%d\"...\n", i, 2*i);
ListInsert_Sq(&L, i, 2*i);
}
printf("\n");
}
PressEnter;
printf("▼12\n▲函数 ListTraverse_Sq 测试...\n"); //12.函数ListTraverse_Sq测试
{
printf(" L 中的元素为L = ");
ListTraverse_Sq(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼5\n▲函数 ListLength_Sq 测试...\n"); //5.函数ListLength_Sq测试
{
i = ListLength_Sq(L);
printf(" L 的长度为 %d \n", i);
printf("\n");
}
PressEnter;
printf("▼11\n▲函数 ListDelete_Sq 测试...\n"); //11.函数ListDelete_Sq测试
{
ListDelete_Sq(&L, 6, &e);
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
printf(" L 中的元素为L = ");
ListTraverse_Sq(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 GetElem_Sq 测试...\n"); //6.函数GetElem_Sq测试
{
GetElem_Sq(L, 4, &e);
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 LocateElem_Sq 测试...\n"); //7.函数LocateElem_Sq测试
{
i = LocateElem_Sq(L, 7, CmpGreater);
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 PriorElem_Sq 测试...\n"); //8.函数PriorElem_Sq测试
{
PriorElem_Sq(L, 6, &e);
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 NextElem_Sq 测试...\n"); //9.函数NextElem_Sq测试
{
NextElem_Sq(L, 6, &e);
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 ClearList_Sq 测试...\n"); //2.函数ClearList_Sq测试
{
printf("清空 L 前:");
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
ClearList_Sq(&L);
printf("清空 L 后:");
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 DestroyList_Sq 测试...\n"); //3.函数DestroyList_Sq测试
{
printf("销毁 L 前:");
L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
DestroyList_Sq(&L);
printf("销毁 L 后:");
L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
Status CmpGreater(LElemType_Sq e, LElemType_Sq data)
{
return data>e ? TRUE : FALSE;
}
void PrintElem(LElemType_Sq e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,180 @@
/***************************************
* *
* 文件夹: ▲02 线性表\01 SequenceList *
* *
* 文件名: SequenceList.c *
* *
* 算 法: 2.3、2.4、2.5、2.6 *
* *
***************************************/
#ifndef SEQUENCELIST_C
#define SEQUENCELIST_C
#include "SequenceList.h" //**▲02 线性表**//
/*════╗
║算法2.3 ║
╚════*/
Status InitList_Sq(SqList *L)
{
(*L).elem = (LElemType_Sq*)malloc(LIST_INIT_SIZE*sizeof(LElemType_Sq));
if(!(*L).elem)
exit(OVERFLOW); //分配内存失败
(*L).length = 0; //初始化顺序表长度为0
(*L).listsize = LIST_INIT_SIZE; //顺序表初始内存分配量
return OK; //初始化成功
}
void ClearList_Sq(SqList *L)
{
(*L).length = 0;
}
void DestroyList_Sq(SqList *L)
{
free((*L).elem);
(*L).elem = NULL; //释放内存后置空指针
(*L).length = 0;
(*L).listsize = 0;
}
Status ListEmpty_Sq(SqList L)
{
return L.length==0 ? TRUE : FALSE;
}
int ListLength_Sq(SqList L)
{
return L.length;
}
Status GetElem_Sq(SqList L, int i, LElemType_Sq *e)
{
if(i<1 || i>L.length)
return ERROR; //i值不合法
else
*e = L.elem[i-1];
return OK;
}
/*════╗
║算法2.6 ║
╚════*/
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq))
{
int i = 1; //i的初值为第一个元素的位序
while(i<=L.length && !Compare(e, L.elem[i-1]))
++i;
if(i<=L.length)
return i;
else
return 0;
}
Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e)
{
int i = 1;
if(L.elem[0]!=cur_e) //第一个结点无前驱
{
while(i<L.length && L.elem[i]!=cur_e)
++i;
if(i<L.length)
{
*pre_e = L.elem[i-1];
return OK;
}
}
return ERROR;
}
Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e)
{
int i = 0;
while(i<L.length && L.elem[i]!=cur_e)
++i;
if(i<L.length-1) //最后一个结点无后继
{
*next_e = L.elem[i+1];
return OK;
}
return ERROR;
}
/*════╗
║算法2.4 ║
╚════*/
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e)
{
LElemType_Sq *newbase;
LElemType_Sq *p, *q;
if(i<1 || i>(*L).length+1)
return ERROR; //i值不合法
if((*L).length >= (*L).listsize) //若存储空间已满,需开辟新空间
{
newbase = (LElemType_Sq*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(LElemType_Sq));
if(!newbase)
exit(OVERFLOW);
(*L).elem = newbase;
(*L).listsize += LISTINCREMENT;
}
q = &(*L).elem[i-1]; //q为插入位置
for(p=&(*L).elem[(*L).length-1]; p>=q; --p)
*(p+1) = *p; //插入位置及之后的元素右移
*q = e; //插入e
(*L).length++; //表长增1
return OK;
}
/*════╗
║算法2.5 ║
╚════*/
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e)
{
LElemType_Sq *p, *q;
if(i<1 || i>(*L).length)
return ERROR; //i值不合法
p = &(*L).elem[i-1]; //p为被删除元素的位置
*e = *p;
q = (*L).elem+(*L).length-1; //表尾元素位置
for(++p; p<=q; ++p)
*(p-1) = *p; //被删元素之后的元素左移
(*L).length--; //表长减1
return OK;
}
Status ListTraverse_Sq(SqList L, void(Visit)(LElemType_Sq))
{
int i;
for(i=0; i<L.length; i++)
Visit(L.elem[i]);
return OK;
}
#endif

View File

@@ -0,0 +1,96 @@
/***************************************
* *
* 文件夹: ▲02 线性表\01 SequenceList *
* *
* 文件名: SequenceList.h *
* *
* 内 容: 顺序表相关操作列表 *
* *
***************************************/
#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
/* 宏定义 */
#define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
#define LISTINCREMENT 10 //顺序表存储空间的分配增量
/* 顺序表类型定义 */
#ifndef LELEMTYPE_SQ
#define LELEMTYPE_SQ
typedef int LElemType_Sq;
#endif
typedef struct
{
LElemType_Sq *elem; //存储空间基址(指向第一个结点的指针)
int length; //当前顺序表长度
int listsize; //当前分配的存储容量
}SqList; //顺序表0号单元正常使用
/* 顺序表函数列表 */
Status InitList_Sq(SqList *L);
/*━━━━━━━━━━━━━━━┓
┃(01)算法2.3初始化空顺序表L。┃
┗━━━━━━━━━━━━━━━*/
void ClearList_Sq(SqList *L);
/*━━━━━━━━━┓
┃(02)清空顺序表L。 ┃
┗━━━━━━━━━*/
void DestroyList_Sq(SqList *L);
/*━━━━━━━━━┓
┃(03)销毁顺序表L。 ┃
┗━━━━━━━━━*/
Status ListEmpty_Sq(SqList L);
/*━━━━━━━━━━━━━┓
┃(04)判断顺序表L是否为空。 ┃
┗━━━━━━━━━━━━━*/
int ListLength_Sq(SqList L);
/*━━━━━━━━━━━━━━┓
┃(05)返回顺序表L中元素个数。 ┃
┗━━━━━━━━━━━━━━*/
Status GetElem_Sq(SqList L, int i, LElemType_Sq *e);
/*━━━━━━━━━━━━━━━━┓
┃(06)用e接收顺序表L中第i个元素。 ┃
┗━━━━━━━━━━━━━━━━*/
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq));
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(07)算法2.6返回顺序表L中首个与e满足Compare关系的元素位序。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e);
/*━━━━━━━━━━━━━━━━━┓
┃(08)用pre_e接收cur_e的前驱。 ┃
┗━━━━━━━━━━━━━━━━━*/
Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e);
/*━━━━━━━━━━━━━━━━━┓
┃(09)用next_e接收cur_e的后继。 ┃
┗━━━━━━━━━━━━━━━━━*/
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e);
/*━━━━━━━━━━━━━━━━━━━━━┓
┃(10)算法2.4在顺序表L的第i个位置上插入e。┃
┗━━━━━━━━━━━━━━━━━━━━━*/
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(11)算法2.5删除顺序表L上第i个位置的元素并用e返回。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status ListTraverse_Sq(SqList L, void (Visit)(LElemType_Sq));
/*━━━━━━━━━━━━━━┓
┃(12)用visit函数访问顺序表L。┃
┗━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,46 @@
/********************************
* *
* 文件夹: ▲02 线性表\02 Union *
* *
* 内 容: 求并集相关函数测试 *
* *
********************************/
#include <stdio.h>
#include "Union.c" //**▲02 线性表**//
void PrintElem(LElemType_Sq e); //测试函数,打印整型
int main(int argc, char **argv)
{
SqList La, Lb;
LElemType_Sq a[5] = {5, 2, 1, 3, 9};
LElemType_Sq b[7] = {7, 2, 6, 9, 11, 3, 10};
int i;
InitList_Sq(&La); //初始化La
for(i=1; i<=5; i++)
ListInsert_Sq(&La, i, a[i-1]);
InitList_Sq(&Lb); //初始化Lb
for(i=1; i<=7; i++)
ListInsert_Sq(&Lb, i, b[i-1]);
printf("La = "); //输出La
ListTraverse_Sq(La, PrintElem);
printf("\n");
printf("Lb = "); //输出Lb
ListTraverse_Sq(Lb, PrintElem);
printf("\n\n");
printf("La = LaLb = "); //输出新表La的内容
Union(&La, Lb);
ListTraverse_Sq(La, PrintElem);
printf("\n\n");
return 0;
}
void PrintElem(LElemType_Sq e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,41 @@
/********************************
* *
* 文件夹: ▲02 线性表\02 Union *
* *
* 文件名: Union.c *
* *
* 算 法: 2.1 *
* *
********************************/
#ifndef UNION_C
#define UNION_C
#include "Union.h" //**▲02 线性表**//
/*════╗
║ 算法2.1║
╚════*/
void Union(SqList *La, SqList Lb)
{
int La_len, Lb_len;
int i;
LElemType_Sq e;
La_len = ListLength_Sq(*La); //求顺序表长度
Lb_len = ListLength_Sq(Lb);
for(i=1; i<=Lb_len; i++)
{
GetElem_Sq(Lb, i, &e); //取Lb中第i个元素赋给e
if(!LocateElem_Sq(*La, e, equal)) //若e不在La中则插入
ListInsert_Sq(La, ++La_len, e);
}
}
Status equal(LElemType_Sq e1, LElemType_Sq e2)
{
return e1==e2 ? TRUE : FALSE;
}
#endif

View File

@@ -0,0 +1,27 @@
/********************************
* *
* 文件夹: ▲02 线性表\02 Union *
* *
* 文件名: Union.h *
* *
* 内 容: 求并集相关操作列表 *
* *
********************************/
#ifndef UNION_H
#define UNION_H
#include "../01 SequenceList/SequenceList.c" //**▲02 线性表**//
/* 并集函数列表 */
void Union(SqList *La, SqList Lb);
/*━━━━━━━━━━━┓
┃(01)算法2.1A=AB。 ┃
┗━━━━━━━━━━━*/
Status equal(LElemType_Sq e1, LElemType_Sq e2);
/*━━━━━━━━━━━━┓
┃(02)判断两元素是否相等。┃
┗━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,51 @@
/**************************************
* *
* 文件夹: ▲02 线性表\03 MergeSqList *
* *
* 内 容: 顺序表归并相关函数测试 *
* *
**************************************/
#include <stdio.h>
#include "MergeSqList.c" //**▲02 线性表**//
void PrintElem(LElemType_Sq e); //测试函数,打印整型
int main(int argc, char **argv)
{
SqList La, Lb, Lc1, Lc2;
LElemType_Sq a[4] = {3, 5, 8, 11};
LElemType_Sq b[7] = {2, 6, 8, 9, 11, 15, 20};
int i;
InitList_Sq(&La); //初始化La
for(i=1; i<=4; i++)
ListInsert_Sq(&La, i, a[i-1]);
InitList_Sq(&Lb); //初始化Lb
for(i=1; i<=7; i++)
ListInsert_Sq(&Lb, i, b[i-1]);
printf("La = "); //输出La
ListTraverse_Sq(La, PrintElem);
printf("\n");
printf("Lb = "); //输出Lb
ListTraverse_Sq(Lb, PrintElem);
printf("\n\n");
MergeSqList_1(La, Lb, &Lc1); //合并A与B,算法2.6
printf("合并La和Lb为Lc1 = "); //输出Lc1
ListTraverse_Sq(Lc1, PrintElem);
printf("\n\n");
MergeSqList_2(La, Lb, &Lc2); //合并A与B,算法2.7
printf("合并La和Lb为Lc2 = "); //输出Lc2
ListTraverse_Sq(Lc2, PrintElem);
printf("\n\n");
return 0;
}
void PrintElem(LElemType_Sq e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,97 @@
/**************************************
* *
* 文件夹: ▲02 线性表\03 MergeSqList *
* *
* 文件名: MergeSqList.c *
* *
* 算 法: 2.2、2.7 *
* *
**************************************/
#ifndef MERGESQLIST_C
#define MERGESQLIST_C
#include "MergeSqList.h" //**▲02 线性表**//
/*════╗
║ 算法2.2║
╚════*/
void MergeSqList_1(SqList La, SqList Lb, SqList *Lc) //调用顺序表函数进行合并
{
int La_len, Lb_len;
int i, j, k;
LElemType_Sq ai, bj;
i = j = 1;
k = 0;
InitList_Sq(Lc); //初始化Lc
La_len = ListLength_Sq(La); //获取La、Lb长度
Lb_len = ListLength_Sq(Lb);
while(i<=La_len && j<=Lb_len) //La及Lb均未扫描完
{
GetElem_Sq(La, i, &ai);
GetElem_Sq(Lb, j, &bj);
if(ai<=bj)
{
ListInsert_Sq(Lc, ++k, ai);
i++;
}
else
{
ListInsert_Sq(Lc, ++k, bj);
j++;
}
}
while(i<=La_len) //表La还未扫描完
{
GetElem_Sq(La, i++, &ai);
ListInsert_Sq(Lc, ++k, ai);
}
while(j<=Lb_len) //表Lb还未扫描完
{
GetElem_Sq(Lb, j++, &bj);
ListInsert_Sq(Lc, ++k, bj);
}
}
/*════╗
║ 算法2.7║
╚════*/
void MergeSqList_2(SqList La, SqList Lb, SqList *Lc)
{
LElemType_Sq *pa, *pb, *pc;
LElemType_Sq *pa_last, *pb_last;
pa = La.elem; //指向La第一个元素
pb = Lb.elem; //指向Lb第一个元素
//不用InitList_Sq创建Lc
(*Lc).listsize = (*Lc).length = La.length + Lb.length;
pc = (*Lc).elem = (LElemType_Sq *)malloc((*Lc).listsize*sizeof(LElemType_Sq));
if(!pc)
exit(OVERFLOW);
pa_last = La.elem + La.length - 1; //指向La最后一个元素
pb_last = Lb.elem + Lb.length - 1; //指向Lb最后一个元素
while(pa<=pa_last && pb<=pb_last) //La和Lb均未扫描完
{
if(*pa <= *pb)
*pc++ = *pa++;
else
*pc++ = *pb++;
}
while(pa <= pa_last) //表La未扫描完
*pc++ = *pa++; //插入La的剩余元素
while(pb <= pb_last) //表Lb未扫描完
*pc++ = *pb++; //插入Lb的剩余元素
}
#endif

View File

@@ -0,0 +1,28 @@
/**************************************
* *
* 文件夹: ▲02 线性表\03 MergeSqList *
* *
* 文件名: MergeSqList.h *
* *
* 内 容: 顺序表归并相关操作列表 *
* *
**************************************/
#ifndef MERGESQLIST_H
#define MERGESQLIST_H
#include <stdlib.h>
#include "../01 SequenceList/SequenceList.c" //**▲02 线性表**//
/* 顺序表归并函数列表 */
void MergeSqList_1(SqList La, SqList Lb, SqList *Lc);
/*━━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.2求C=A+BA,B,C均为非递减序列 ┃
┗━━━━━━━━━━━━━━━━━━━━━*/
void MergeSqList_2(SqList La, SqList Lb, SqList *Lc);
/*━━━━━━━━━━━━━━━━━━━━━┓
┃(02)算法2.7求C=A+BA,B,C均为非递减序列 ┃
┗━━━━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,164 @@
/*******************************************
* *
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
* *
* 内 容: 单链表相关函数测试 *
* *
*******************************************/
#include <stdio.h>
#include "SinglyLinkedList.c" //**▲02 线性表**//
/* 函数原型 */
Status CmpGreater(LElemType_L e, LElemType_L data); //判断data是否大于e //若data大于e返回TRUE
void PrintElem(LElemType_L e); //测试函数,打印整型
int main(int argc, char **argv)
{
LinkList L;
int i;
LElemType_L e;
printf("▼1\n▲函数 InitList_L 测试...\n"); //1.函数InitList_L测试
{
printf("初始化单链表 L ...\n");
InitList_L(&L);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 ListEmpty_L 测试...\n"); //4.函数ListEmpty_L测试
{
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼10\n▲函数 ListInsert_L 测试...\n"); //10.函数ListInsert_L测试
{
for(i=1; i<=6; i++)
{
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
ListInsert_L(L, i, 2*i);
}
printf("\n");
}
PressEnter;
printf("▼12\n▲函数 ListTraverse_L 测试...\n"); //12.函数ListTraverse_L测试
{
printf(" L 中的元素为L = ");
ListTraverse_L(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼5\n▲函数 ListLength_L 测试...\n"); //5.函数ListLength_L测试
{
printf(" L 的长度为 %d \n", ListLength_L(L));
printf("\n");
}
PressEnter;
printf("▼11\n▲函数 ListDelete_L 测试...\n"); //11.函数ListDelete_L测试
{
ListDelete_L(L, 6, &e);
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
printf(" L 中的元素为L = ");
ListTraverse_L(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 GetElem_L 测试...\n"); //6.函数GetElem_L测试
{
GetElem_L(L, 4, &e);
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 LocateElem_L 测试...\n"); //7.函数LocateElem_L测试
{
i = LocateElem_L(L, 13, CmpGreater);
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 PriorElem_L 测试...\n"); //8.函数PriorElem_L测试
{
PriorElem_L(L, 6, &e);
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 NextElem_L 测试...\n"); //9.函数NextElem_L测试
{
NextElem_L(L, 6, &e);
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 ClearList_L 测试...\n"); //2.函数ClearList_L测试
{
printf("清空 L 前:");
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
ClearList_L(L);
printf("清空 L 后:");
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 DestroyList_L 测试...\n"); //3.函数DestroyList_L测试
{
printf("销毁 L 前:");
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
DestroyList_L(&L);
printf("销毁 L 后:");
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
printf("\n");
}
PressEnter;
printf("▼13\n▲函数 CreateList_HL 测试...\n"); //13.函数CreateList_HL测试
{
FILE *fp;
LinkList L;
printf("头插法建立单链表 L = ");
fp = fopen("TestData_HL.txt", "r"); //文件指针,指向数据源
CreateList_HL(fp, &L, 5);
fclose(fp);
ListTraverse_L(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼14\n▲函数 CreateList_TL 测试...\n"); //14.函数CreateList_TL测试
{
FILE *fp;
LinkList L;
printf("尾插法建立单链表 L = ");
fp = fopen("TestData_TL.txt", "r"); //文件指针,指向数据源
CreateList_TL(fp, &L, 5);
fclose(fp);
ListTraverse_L(L, PrintElem);
printf("\n\n");
}
PressEnter;
return 0;
}
Status CmpGreater(LElemType_L e, LElemType_L data)
{
return data>e ? TRUE : FALSE;
}
void PrintElem(LElemType_L e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,337 @@
/*******************************************
* *
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
* *
* 文件名: SinglyLinkedList.c *
* *
* 算 法: 2.8、2.9、2.10、2.11 *
* *
*******************************************/
#ifndef SINGLYLINKEDLIST_C
#define SINGLYLINKEDLIST_C
#include "SinglyLinkedList.h" //**▲02 线性表**//
Status InitList_L(LinkList *L)
{
(*L) = (LinkList)malloc(sizeof(LNode));
if(!(*L))
exit(OVERFLOW);
(*L)->next = NULL;
return OK;
}
Status ClearList_L(LinkList L) //保留头结点
{
LinkList pre, p;
if(!L)
return ERROR;
pre = L->next;
while(pre)
{
p = pre->next;
free(pre);
pre = p;
}
L->next = NULL;
return OK;
}
void DestroyList_L(LinkList *L) //销毁所有结点
{
LinkList p = *L;
while(p)
{
p = (*L)->next;
free(*L);
(*L) = p;
}
}
Status ListEmpty_L(LinkList L)
{
if(L!=NULL && L->next==NULL) //链表存在且只有头结点
return TRUE;
else
return FALSE;
}
int ListLength_L(LinkList L)
{
LinkList p;
int i;
if(L)
{
i = 0;
p = L->next;
while(p)
{
i++;
p = p->next;
}
}
return i;
}
/*════╗
║ 算法2.8║
╚════*/
Status GetElem_L(LinkList L, int i, LElemType_L *e)
{
int j;
LinkList p = L->next;
j = 1;
p = L->next;
while(p && j<i) //p不为空且还未到达i处
{
j++;
p = p->next;
}
if(!p || j>i) //第i个元素不存在
return ERROR;
*e = p->data;
return OK;
}
int LocateElem_L(LinkList L, LElemType_L e, Status(Compare)(LElemType_L, LElemType_L))
{
int i;
LinkList p;
i = -1; //L不存在时返回-1
if(L)
{
i = 0;
p = L->next;
while(p)
{
i++;
if(!Compare(e, p->data))
{
p = p->next;
if(p==NULL) //失配时已经是最后一个结点
i++;
}
else
break;
}
}
return i;
}
/* 银行排队算法中,此处两个函数不能直接使用,原因是结构不能直接比较 */
#ifndef BANKQUEUING_C
Status PriorElem_L(LinkList L, LElemType_L cur_e, LElemType_L *pre_e)
{
LinkList p, suc;
if(L)
{
p = L->next;
if(p->data!=cur_e) //第一个结点无前驱
{
while(p->next) //若p结点有后继
{
suc = p->next; //suc指向p的后继
if(suc->data==cur_e)
{
*pre_e = p->data;
return OK;
}
p = suc;
}
}
}
return ERROR;
}
Status NextElem_L(LinkList L, LElemType_L cur_e, LElemType_L *next_e)
{
LinkList p, suc;
if(L)
{
p = L->next;
while(p && p->next)
{
suc = p->next;
if(suc && p->data==cur_e)
{
*next_e = suc->data;
return OK;
}
if(suc)
p = suc;
else
break;
}
}
return ERROR;
}
#endif
/*════╗
║ 算法2.9║
╚════*/
Status ListInsert_L(LinkList L, int i, LElemType_L e)
{
LinkList p, s;
int j;
p = L;
j = 0;
while(p && j<i-1) //寻找第i-1个结点
{
p = p->next;
++j;
}
if(!p || j>i-1)
return ERROR;
s = (LinkList)malloc(sizeof(LNode));
if(!s)
exit(OVERFLOW);
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
/*═════╗
║ 算法2.10 ║
╚═════*/
Status ListDelete_L(LinkList L, int i, LElemType_L *e)
{
LinkList pre, p;
int j;
pre = L;
j = 1;
while(pre->next && j<i) //寻找第i个结点并令pre指向其前驱
{
pre = pre->next;
++j;
}
if(!pre->next || j>i) //删除位置不合理
return ERROR;
p = pre->next;
pre->next = p->next;
*e = p->data;
free(p);
return OK;
}
Status ListTraverse_L(LinkList L, void(Visit)(LElemType_L))
{
LinkList p;
if(!L)
return ERROR;
else
p = L->next;
while(p)
{
Visit(p->data);
p = p->next;
}
return OK;
}
/*═════╗
║ 算法2.11 ║
╚═════*/
Status CreateList_HL(FILE *fp, LinkList *L, int n)
{
int i;
LinkList p;
LElemType_L tmp;
*L = (LinkList)malloc(sizeof(LNode));
if(!(*L))
exit(OVERFLOW);
(*L)->next = NULL; //建立头结点
for(i=1; i<=n; ++i)
{
if(Scanf(fp, "%d", &tmp)==1)
{
p = (LinkList)malloc(sizeof(LNode));
if(!p)
exit(OVERFLOW);
p->data = tmp; //录入数据
p->next = (*L)->next;
(*L)->next = p;
}
else
return ERROR;
}
return OK;
}
Status CreateList_TL(FILE *fp, LinkList *L, int n)
{
int i;
LinkList p, q;
LElemType_L tmp;
*L = (LinkList)malloc(sizeof(LNode));
if(!(*L))
exit(OVERFLOW);
(*L)->next = NULL;
for(i=1,q=*L; i<=n; ++i)
{
if(Scanf(fp, "%d", &tmp)==1)
{
p = (LinkList)malloc(sizeof(LNode));
if(!p)
exit(OVERFLOW);
p->data = tmp; //录入数据
q->next = p;
q = q->next;
}
else
return ERROR;
}
q->next = NULL;
return OK;
}
#endif

View File

@@ -0,0 +1,103 @@
/*******************************************
* *
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
* *
* 文件名: SinglyLinkedList.h *
* *
* 内 容: 单链表相关操作列表 *
* *
*******************************************/
#ifndef SINGLYLINKEDLIST_H
#define SINGLYLINKEDLIST_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
/* 单链表类型定义 */
#ifndef BANKQUEUING_H /*后续的模拟银行排队算法中,此类型需要重新定义*/
typedef int LElemType_L;
/* 单链表结构体 */
typedef struct LNode
{
LElemType_L data;
struct LNode* next;
}LNode;
typedef LNode* LinkList; //指向单链表结点的指针
#endif
/* 单链表(带头结点)函数列表 */
Status InitList_L(LinkList *L);
/*━━━━━━━━━━┓
┃(01)初始化单链表L。 ┃
┗━━━━━━━━━━*/
Status ClearList_L(LinkList L);
/*━━━━━━━━━━━━━━━┓
┃(02)置空单链表L头结点保留。 ┃
┗━━━━━━━━━━━━━━━*/
void DestroyList_L(LinkList *L);
/*━━━━━━━━━━━━━━━━━━━┓
┃(03)销毁单链表L连同通结点一起销毁。 ┃
┗━━━━━━━━━━━━━━━━━━━*/
Status ListEmpty_L(LinkList L);
/*━━━━━━━━━━━━━━━┓
┃(04)判断单链表L是否为空。 ┃
┗━━━━━━━━━━━━━━━*/
int ListLength_L(LinkList L);
/*━━━━━━━━━━━━┓
┃(05)返回单链表L元素个数 ┃
┗━━━━━━━━━━━━*/
Status GetElem_L(LinkList L, int i, LElemType_L *e);
/*━━━━━━━━━━━━━━━━━━━┓
┃(06)算法2.8用e接收单链表L中第i个元素┃
┗━━━━━━━━━━━━━━━━━━━*/
int LocateElem_L(LinkList L, LElemType_L e, Status(Compare)(LElemType_L, LElemType_L));
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(07)返回单链表L中第一个与e满足Compare关系的元素位序。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status PriorElem_L(LinkList L, LElemType_L cur_e, LElemType_L *pre_e);
/*━━━━━━━━━━━━━━┓
┃(08)用pre_e接收cur_e的前驱。┃
┗━━━━━━━━━━━━━━*/
Status NextElem_L(LinkList L, LElemType_L cur_e, LElemType_L *next_e);
/*━━━━━━━━━━━━━━━┓
┃(09)用next_e接收cur_e的后继。 ┃
┗━━━━━━━━━━━━━━━*/
Status ListInsert_L(LinkList L, int i, LElemType_L e);
/*━━━━━━━━━━━━━━━━━━━━━┓
┃(10)算法2.9在单链表L第i个位置之前插入e。┃
┗━━━━━━━━━━━━━━━━━━━━━*/
Status ListDelete_L(LinkList L, int i, LElemType_L *e);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(11)算法2.10删除单链表L第i个位置的值并用e接收。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status ListTraverse_L(LinkList L, void(Visit)(LElemType_L));
/*━━━━━━━━━━━━━━┓
┃(12)用Visit函数访问单链表L。┃
┗━━━━━━━━━━━━━━*/
Status CreateList_HL(FILE *fp, LinkList *L, int n);
/*━━━━━━━━━━━━━━━━━━━━━━┓
┃(13)算法2.11头插法建立单链表L(逆序输入)。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━*/
Status CreateList_TL(FILE *fp, LinkList *L, int n);
/*━━━━━━━━━━━━━━━━━┓
┃(14)尾插法建立单链表L(顺序输入)。 ┃
┗━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1 @@
降序9 7 5 3 1

View File

@@ -0,0 +1 @@
升序2 4 6 8 10

View File

@@ -0,0 +1,50 @@
/************************************
* *
* 文件夹: ▲02 线性表\05 MergeList *
* *
* 内 容: 单链表归并相关函数测试 *
* *
************************************/
#include <stdio.h>
#include "MergeList.c" //**▲02 线性表**//
void PrintElem(LElemType_L e); //测试函数,打印整型
int main(int argc, char **argv)
{
FILE *fp;
LinkList La, Lb, Lc;
int m;
m = 5;
printf("作为示例La长度设定为 %d Lb设定为 %d 创建La和Lb...\n", m, m);
fp = fopen("TestData_HL.txt", "r"); //文件指针,指向数据源
CreateList_HL(fp, &La, m);
fclose(fp);
fp = fopen("TestData_TL.txt", "r"); //文件指针,指向数据源
CreateList_TL(fp, &Lb, m);
fclose(fp);
printf("La = ");
ListTraverse_L(La, PrintElem);
printf("\n");
printf("Lb = ");
ListTraverse_L(Lb, PrintElem);
printf("\n\n");
PressEnter;
MergeList_L(La, &Lb, &Lc);
printf("合并La和Lb为Lc = ");
ListTraverse_L(Lc, PrintElem);
printf("\n\n");
PressEnter;
return 0;
}
void PrintElem(LElemType_L e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,49 @@
/************************************
* *
* 文件夹: ▲02 线性表\05 MergeList *
* *
* 文件名: MergeList.c *
* *
* 算 法: 2.12 *
* *
************************************/
#ifndef MERGELIST_C
#define MERGELIST_C
#include "MergeList.h" //**▲02 线性表**//
/*═════╗
║ 算法2.12 ║
╚═════*/
void MergeList_L(LinkList La, LinkList *Lb, LinkList *Lc)
{ //指针Lb,Lc要改变故形参是指向指针的指针
LinkList pa, pb, pc;
pa = La->next;
pb = (*Lb)->next;
pc = *Lc = 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的头结点
*Lb = NULL;
}
#endif

View File

@@ -0,0 +1,24 @@
/************************************
* *
* 文件夹: ▲02 线性表\05 MergeList *
* *
* 文件名: MergeList.h *
* *
* 内 容: 单链表归并相关操作列表 *
* *
************************************/
#ifndef MERGELIST_H
#define MERGELIST_H
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../04 SinglyLinkedList/SinglyLinkedList.c" //**▲02 线性表**//
/* 单链表归并函数列表 */
void MergeList_L(LinkList La, LinkList *Lb, LinkList *Lc);
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.12C=A+B且保持元素相对位置不变。 ┃
┃ Lc利用La的头结点Lb中结点均插入新链表Lc中。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1 @@
降序9 7 5 3 1

View File

@@ -0,0 +1 @@
升序2 4 6 8 10

View File

@@ -0,0 +1,136 @@
/********************************
* *
* 文件夹: ▲02 线性表 *
* *
* 内 容: 静态链表相关函数测试 *
* *
********************************/
#include <stdio.h>
#include "StaticLinkedList.c" //**▲02 线性表**//
void PrintElem(LElemType_S e); //测试函数,打印整型
int main(int argc, char **argv)
{
SLinkList H;
LElemType_S e;
int i;
printf("▼1\n▲函数InitSpace_SL测试...\n"); //1.函数InitSpace_SL测试
{
printf("初始化静态链表的备用空间 SPACE ...\n");
InitSpace_SL();
printf("\n");
}
PressEnter;
printf("▼2、4\n▲函数Malloc_SL、InitList_SL测试...\n");//4.函数Malloc_SL、InitList_SL测试
{
printf("初始化静态链表 H 用Malloc_SL申请空间...\n");
InitList_SL(&H);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数ListEmpty_SL测试...\n"); //7.函数ListEmpty_SL测试
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
printf("\n");
PressEnter;
printf("▼13\n▲函数ListInsert_SL测试...\n"); //13.函数ListInsert_SL测试
{
for(i=1; i<=6; i++)
{
printf("在 H 第 %d 个位置插入\"%d\" ...\n", i, 2*i);
ListInsert_SL(H, i, 2*i);
}
printf("\n");
}
PressEnter;
printf("▼15\n▲函数ListTraverse_SL测试...\n"); //15.函数ListTraverse_SL测试
{
printf(" H 中的元素为H = ");
ListTraverse_SL(H, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼8\n▲函数ListLength_SL测试...\n"); //8.函数ListLength_SL测试
{
printf(" H 的长度为 %d \n", ListLength_SL(H));
printf("\n");
}
PressEnter;
printf("▼3、14\n▲函数Free_SL、ListDelete_SL测试...\n");//3、14.函数Free_SL、ListDelete_SL测试
{
ListDelete_SL(H, 6, &e);
printf("删除 H 中第 6 个元素 \"%d\" 用Free_SL释放空间...\n", e);
printf(" H 的元素为H = ");
ListTraverse_SL(H, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼9\n▲函数GetElem_SL测试...\n"); //9.函数GetElem_SL测试
{
GetElem_SL(H, 4, &e);
printf(" H 中第 4 个位置的元素为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼10\n▲函数LocateElem_SL测试...\n"); //10.函数LocateElem_SL测试
{
printf("元素 \"8\" 在 H 中的位序为 %d \n", LocateElem_SL(H, 8));
printf("\n");
}
PressEnter;
printf("▼11\n▲函数PriorElem_SL测试...\n"); //11.函数PriorElem_SL测试
{
PriorElem_SL(H, 6, &e);
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼12\n▲函数NextElem_SL测试...\n"); //12.函数NextElem_SL测试
{
NextElem_SL(H, 6, &e);
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼5\n▲函数ClearList_SL测试...\n"); //5.函数ClearList_SL测试
{
printf("清空 H 前:");
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
ClearList_SL(H);
printf("清空 H 后:");
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼6\n▲函数DestroyList_SL测试...\n"); //6.函数DestroyList_SL测试
{
printf("销毁 H 前:");
H ? printf(" H 存在!\n") : printf(" H 不存在!!\n");
DestroyList_SL(&H);
printf("销毁 H 后:");
H ? printf(" H 存在!\n") : printf(" H 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
void PrintElem(LElemType_S e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,307 @@
/**********************************
* *
* 文件夹: ▲02 线性表 *
* *
* 文件名: StaticLinkedList.c *
* *
* 算 法: 2.13、2.14、2.15、2.16 *
* *
**********************************/
#ifndef STATICLINKEDLIST_C
#define STATICLINKEDLIST_C
#include "StaticLinkedList.h" //**▲02 线性表**//
/*═════╗
║ 算法2.14 ║
╚═════*/
void InitSpace_SL() //首先初始化备用空间
{
int i; //0号单元做备用空间的起始结点
for(i=0; i<MAXSIZE-1; i++) //各空间结点首尾相接
SPACE[i].cur = i + 1;
SPACE[MAXSIZE-1].cur = 0;
}
/*═════╗
║ 算法2.15 ║
╚═════*/
int Malloc_SL() //从备用空间申请结点空间
{
int i;
i = SPACE[0].cur;
if(SPACE[0].cur)
{
SPACE[0].cur = SPACE[i].cur; //将申请到的空间从备用空间中删去
return i; //返回新申请结点下标
}
else
return 0; //申请失败返回0
}
/*═════╗
║ 算法2.16 ║
╚═════*/
void Free_SL(int k) //回收k结点空间
{
SPACE[k].cur = SPACE[0].cur;
SPACE[0].cur = k;
}
Status InitList_SL(SLinkList *H) //H为头结点指针
{
*H = Malloc_SL(); //创建头结点
if(!(*H))
exit(OVERFLOW); //“内存”已满
SPACE[*H].cur = 0; //头结点游标置为0
return OK;
}
Status ClearList_SL(SLinkList H)
{
int p, q;
if(!H)
return ERROR;
p = SPACE[H].cur; //p指向第一个结点
while(p) //从链表首结点开始删除
{
SPACE[H].cur = SPACE[p].cur;
Free_SL(p);
p = SPACE[H].cur;
}
return OK;
}
void DestroyList_SL(SLinkList *H)
{
ClearList_SL(*H); //清空静态链表
Free_SL(*H); //释放头结点
*H = 0;
}
Status ListEmpty_SL(SLinkList H)
{
if(H && !SPACE[H].cur) //只有头结点
return TRUE;
else
return FALSE;
}
int ListLength_SL(SLinkList H)
{
int count; //计数器
int p;
if(!H)
exit(OVERFLOW);
count = 0;
p = SPACE[H].cur;
while(p)
{
count++;
p = SPACE[p].cur;
}
return count;
}
Status GetElem_SL(SLinkList H, int i, LElemType_S *e)
{
int count, p;
if(!H || i<1 || i>MAXSIZE-2)
return ERROR;
count = 0;
p = SPACE[H].cur;
while(p)
{
count++;
if(count==i)
{
*e = SPACE[p].data;
return OK;
}
p = SPACE[p].cur;
}
}
/*═════╗
║ 算法2.13 ║
╚═════*/
int LocateElem_SL(SLinkList H, LElemType_S e)
{
int k, count;
count = 1;
if(H && SPACE[H].cur)
{
k = SPACE[H].cur;
while(k && SPACE[k].data!=e)
{
count++;
k = SPACE[k].cur;
}
if(k)
return count;
}
return 0;
}
Status PriorElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *pre_e)
{
int p, q;
if(H)
{
p = SPACE[H].cur;
if(p && SPACE[p].data!=cur_e)
{
q = SPACE[p].cur;
while(q && SPACE[q].data!=cur_e)
{
p = q;
q= SPACE[q].cur;
}
if(q) //找到了cur_e
{
*pre_e = SPACE[p].data;
return OK;
}
}
}
return ERROR;
}
Status NextElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *next_e)
{
int p;
if(H)
{
p = SPACE[H].cur;
while(p && SPACE[p].data!=cur_e)
p = SPACE[p].cur;
if(p && SPACE[p].cur) //找到了cur_e且不是最后一个结点
{
p = SPACE[p].cur;
*next_e = SPACE[p].data;
return OK;
}
}
return ERROR;
}
Status ListInsert_SL(SLinkList H, int i, LElemType_S e)
{
int count, k, p;
if(!H) //链表不存在
return ERROR;
if(i>0)
{
count = 0;
k = H; //k指向头结点
while(k && count<i-1) //寻找插入位置的前一个位置
{
count++;
k = SPACE[k].cur;
}
if(k) //找到了第i-1个元素的位置
{
p = Malloc_SL();
if(!p) //申请空间失败
return ERROR;
SPACE[p].data = e; //插入元素e
SPACE[p].cur = SPACE[k].cur;
SPACE[k].cur = p;
return OK;
}
}
return ERROR;
}
Status ListDelete_SL(SLinkList H, int i, LElemType_S *e)
{
int count, k, p;
if(!H) //链表不存在
return ERROR;
if(i>0)
{
count = 0;
k = H; //k指向头结点
while(k && count<i-1) //寻找插入位置的前一个位置
{
count++;
k = SPACE[k].cur;
}
if(k && SPACE[k].cur) //找到了第i-1个元素的位置且不是最后一个元素
{
p = SPACE[k].cur; //p指向要被删除的结点
*e = SPACE[p].data;
SPACE[k].cur = SPACE[p].cur;
Free_SL(p);
return OK;
}
}
return ERROR;
}
Status ListTraverse_SL(SLinkList H, void(Visit)(LElemType_S))
{
int p;
if(!H)
return ERROR; //静态链表不存在或为空
p = SPACE[H].cur;
while(p)
{
Visit(SPACE[p].data);
p = SPACE[p].cur;
}
return OK;
}
#endif

View File

@@ -0,0 +1,115 @@
/********************************
* *
* 文件夹: ▲02 线性表 *
* *
* 文件名: StaticLinkedList.h *
* *
* 内 容: 静态链表相关操作列表 *
* *
********************************/
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
★备注: ┃
★1.为操作方便,特为申请到的空间段设一“头结点”。┃
★2.模拟系统动态申请空间过程。 ┃
★3.个别操作会与严蔚敏数据结构课本有所差异。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
#ifndef STATICLINKEDLIST_H
#define STATICLINKEDLIST_H
#include <stdlib.h> ////提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
/* 宏定义 */
#define MAXSIZE 1000 //静态链表的最大长度
/* 静态链表类型定义 */
typedef int SLinkList; //静态链表类型
typedef int LElemType_S;
typedef struct
{
LElemType_S data;
int cur; //cur是游标做指针用区别于数组下标
}Component[MAXSIZE]; //链表空间类型
/* 全局变量 */
Component SPACE; //静态链表空间
/* 静态链表函数列表 */
void InitSpace_SL();
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.14将一维数组SPACE中各分量链成一个大的备用空间。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
int Malloc_SL();
/*━━━━━━━━━━━━━━━━━┓
┃(02)算法2.15:为插入数据申请空间。┃
┗━━━━━━━━━━━━━━━━━*/
void Free_SL(int k);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(03)算法2.16将下标为k的空闲结点回收。 ┃
┗━━━━━━━━━━━━━━━━━━━━*/
int InitList_SL(SLinkList *H);
/*━━━━━━━━━━━━━━━━┓
┃(04)初始化静态链表,建立头结点。┃
┗━━━━━━━━━━━━━━━━*/
Status ClearList_SL(SLinkList H);
/*━━━━━┓
┃(05)置空。┃
┗━━━━━*/
void DestroyList_SL(SLinkList *H);
/*━━━━━┓
┃(06)销毁。┃
┗━━━━━*/
Status ListEmpty_SL(SLinkList H);
/*━━━━━┓
┃(07)判空。┃
┗━━━━━*/
int ListLength_SL(SLinkList H);
/*━━━━━┓
┃(08)求长。┃
┗━━━━━*/
Status GetElem_SL(SLinkList H, int i, LElemType_S *e);
/*━━━━━┓
┃(09)取值。┃
┗━━━━━*/
int LocateElem_SL(SLinkList H, LElemType_S e);
/*━━━━━━━━━━━━━━━━┓
┃(10)算法2.13返回元素e的位序。 ┃
┗━━━━━━━━━━━━━━━━*/
Status PriorElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *pre_e);
/*━━━━━┓
┃(11)前驱。┃
┗━━━━━*/
Status NextElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *next_e);
/*━━━━━┓
┃(12)后继。┃
┗━━━━━*/
Status ListInsert_SL(SLinkList H, int i, LElemType_S e);
/*━━━━━┓
┃(13)插入。┃
┗━━━━━*/
Status ListDelete_SL(SLinkList H, int i, LElemType_S *e);
/*━━━━━┓
┃(14)删除。┃
┗━━━━━*/
Status ListTraverse_SL(SLinkList H, void(Visit)(LElemType_S));
/*━━━━━┓
┃(15)访问。┃
┗━━━━━*/
#endif

View File

@@ -0,0 +1,51 @@
/*************************************
* *
* 文件夹: ▲02 线性表\07 Difference *
* *
* 内 容: 算法2.17相关函数测试 *
* *
*************************************/
#include <stdio.h>
#include "Difference.c" //**▲02 线性表**//
void PrintElem(LElemType_S e); //测试函数,打印整型
int main(int argc, char **argv)
{
SLinkList S;
FILE *fp;
int len_A, len_B, i;
LElemType_S A[100], B[100];
len_A = 3;
len_B = 5;
fp = fopen("TestData.txt", "r"); //文件指针,指向数据源
for(i=0; i<len_A; i++) //集合A
Scanf(fp, "%d", &A[i]);
for(i=0; i<len_B; i++) //集合B
Scanf(fp, "%d", &B[i]);
fclose(fp);
printf("A = ");
for(i=0; i<len_A; i++)
PrintElem(A[i]);
printf("\n");
printf("B = ");
for(i=0; i<len_B; i++)
PrintElem(B[i]);
printf("\n\n");
printf("S = (A-B)(B-A) = ");
difference(&S, A, len_A, B, len_B);
ListTraverse_SL(S, PrintElem);
printf("\n\n");
return 0;
}
void PrintElem(LElemType_S e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,67 @@
/*************************************
* *
* 文件夹: ▲02 线性表\07 Difference *
* *
* 文件名: Difference.c *
* *
* 算 法: 2.17 *
* *
*************************************/
#ifndef DIFFERENCE_C
#define DIFFERENCE_C
#include "Difference.h" //**▲02 线性表**//
/*═════╗
║ 算法2.17 ║
╚═════*/
void difference(SLinkList *S, LElemType_S A[], int len_A, LElemType_S B[], int len_B)
{
int i, j;
int r, p, k;
LElemType_S b;
InitSpace_SL();
*S = Malloc_SL(); //头结点
r = *S; //r指向S的当前最后结点尾指针
SPACE[r].cur = 0;
for(j=0; j<len_A; j++) //建立集合A的链表
{
i = Malloc_SL(); //申请结点
SPACE[i].data = A[j]; //录入A的元素值
SPACE[r].cur = i; //插入到表尾
r = i;
}
SPACE[r].cur =0; //尾结点指针为空
for(j=0; j<len_B; j++) //录入B的元素值
{
b = B[j];
p = *S; //p指向集合A的头结点
k = SPACE[*S].cur; //k指向集合A的第一个结点
while(k && SPACE[k].data!=b)
{ //在集合A中查找b
p = k;
k = SPACE[k].cur;
}
if(!k) //A中找不到b则将b插入A
{ //新增元素将插入r结点的尾部
i = Malloc_SL();
SPACE[i].data = b;
SPACE[i].cur = SPACE[r].cur;
SPACE[r].cur = i; //r始终指向最后从A中插入的元素
}
else //A中存在b则将b从A中删除
{
SPACE[p].cur = SPACE[k].cur;
Free_SL(k);
if(k==r)
r = p;
}
}
}
#endif

View File

@@ -0,0 +1,24 @@
/*************************************
* *
* 文件夹: ▲02 线性表\07 Difference *
* *
* 文件名: Difference.h *
* *
* 内 容: 算法2.17相关操作列表 *
* *
*************************************/
#ifndef DIFFERENCE_H
#define DIFFERENCE_H
#include <stdio.h>
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
#include "../06 StaticLinkedList/StaticLinkedList.c" //**▲02 线性表**//
/* 算法2.17函数列表 */
void difference(SLinkList *S, LElemType_S A[], int len_A, LElemType_S B[], int len_B);
/*━━━━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.17:在一维数组中建立集合(A-B)(B-A)┃
┗━━━━━━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,2 @@
集合A2 3 4
集合B1 3 4 6 7

View File

@@ -0,0 +1,146 @@
/**********************************************
* *
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
* *
* 内 容: 双循环链表相关函数测试 *
* *
**********************************************/
#include <stdio.h>
#include "DualCycleLinkedList.c" //**▲02 线性表**//
Status CmpGreater(LElemType_DC e, LElemType_DC data); //若data>e返回TRUE否则返回FALSE
void PrintElem(LElemType_DC e); //测试函数,打印整型
int main(int argc, char **argv)
{
DuLinkList L;
int i;
LElemType_DC e;
printf("▼1\n▲函数 InitList_DuL 测试...\n"); //1.函数InitList_DuL测试
{
printf("初始化双循环链表 L ...\n");
InitList_DuL(&L);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 ListEmpty_DuL 测试...\n"); //4.函数ListEmpty_DuL测试
{
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼11\n▲函数 ListInsert_DuL 测试...\n"); //11.函数ListInsert_DuL测试
{
for(i=1; i<=6; i++)
{
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
ListInsert_DuL(L, i, 2*i);
}
printf("\n");
}
PressEnter;
printf("▼13\n▲函数 ListTraverse_DuL 测试...\n"); //13.函数ListTraverse_DuL测试
{
printf(" L 中的元素为L = ");
ListTraverse_DuL(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼5\n▲函数 ListLength_DuL 测试...\n"); //5.函数ListLength_DuL测试
{
printf(" L 的长度为 %d \n", ListLength_DuL(L));
printf("\n");
}
PressEnter;
printf("▼12\n▲函数 ListDelete_DuL 测试...\n"); //12.函数ListDelete_DuL测试
{
ListDelete_DuL(L, 6, &e);
printf("删除 L 中第6个元素 \"%d\" ...\n", e);
printf(" L 中的元素为L = ");
ListTraverse_DuL(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 GetElem_DuL 测试...\n"); //6.函数GetElem_DuL测试
{
GetElem_DuL(L, 4, &e);
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 LocateElem_DuL 测试...\n"); //7.函数LocateElem_DuL测试
{
i = LocateElem_DuL(L, 7, CmpGreater);
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 PriorElem_DuL 测试...\n"); //8.函数PriorElem_DuL测试
{
PriorElem_DuL(L, 6, &e);
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 NextElem_DuL 测试...\n"); //9.函数NextElem_DuL测试
{
NextElem_DuL(L, 6, &e);
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼10\n▲函数 GetElem_P 测试...\n"); //10.函数GetElem_P测试
{
DuLinkList p;
p = GetElemPtr_DuL(L, 3);
printf("链表第 3 个结点的指针为 0x%x其对应的值为 \"%d\" \n", p, *p);
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 ClearList_DuL 测试...\n"); //3.函数ClearList_DuL测试
{
printf("清空 L 前:");
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
ClearList_DuL(L);
printf("清空 L 后:");
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 DestroyList_DuL 测试...\n"); //2.函数DestroyList_DuL测试
{
printf("销毁 L 前:");
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
DestroyList_DuL(&L);
printf("销毁 L 后:");
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
Status CmpGreater(LElemType_DC e, LElemType_DC data)
{
return data>e ? TRUE : FALSE;
}
void PrintElem(LElemType_DC e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,258 @@
/**********************************************
* *
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
* *
* 文件名: DualCycleLinkedList.c *
* *
* 算 法: 2.18、2.19 *
* *
**********************************************/
#ifndef DUALCYCLELINKEDLIST_C
#define DUALCYCLELINKEDLIST_C
#include "DualCycleLinkedList.h" //**▲02 线性表**//
Status InitList_DuL(DuLinkList *L)
{
*L = (DuLinkList)malloc(sizeof(DuLNode));
if(!(*L))
exit(OVERFLOW);
(*L)->next = (*L)->prior = *L;
return OK;
}
Status ClearList_DuL(DuLinkList L)
{
DuLinkList p, q;
p = L->next;
while(p!=L)
{
q = p->next;
free(p);
p = q;
}
L->next = L->prior = L;
return OK;
}
void DestroyList_DuL(DuLinkList *L)
{
ClearList_DuL(*L);
free(*L);
*L = NULL;
}
Status ListEmpty_DuL(DuLinkList L)
{
if(L && L->next==L && L->prior==L)
return TRUE;
else
return FALSE;
}
int ListLength_DuL(DuLinkList L)
{
DuLinkList p;
int count;
if(L)
{
count = 0;
p = L; //p指向头结点
while(p->next!=L) //p没到表头
{
count++;
p = p->next;
}
}
return count;
}
Status GetElem_DuL(DuLinkList L, int i, LElemType_DC *e)
{
DuLinkList p;
int count;
if(L)
{
count = 1;
p = L->next;
while(p!=L && count<i)
{
count++;
p = p->next;
}
if(p!=L)
{
*e = p->data;
return OK;
}
}
return ERROR;
}
int LocateElem_DuL(DuLinkList L, LElemType_DC e, Status(Compare)(LElemType_DC, LElemType_DC))
{
DuLinkList p;
int count;
if(L)
{
count = 1;
p = L->next;
while(p!=L && !Compare(e, p->data))
{
count++;
p = p->next;
}
if(p!=L)
return count;
}
return 0;
}
Status PriorElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *pre_e)
{
DuLinkList p;
if(L)
{
p = L->next;
while(p!=L && p->data!=cur_e)
p = p->next;
if(p!=L && p->prior!=L) //p不为首结点
{
*pre_e = p->prior->data;
return OK;
}
}
return ERROR;
}
Status NextElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *next_e)
{
DuLinkList p;
if(L)
{
p = L->next;
while(p!=L && p->data!=cur_e)
p = p->next;
if(p!=L && p->next!=L)
{
*next_e = p->next->data;
return OK;
}
}
return ERROR;
}
DuLinkList GetElemPtr_DuL(DuLinkList L, int i)
{
int count;
DuLinkList p;
if(L && i>0)
{
count = 1;
p = L->next;
while(p!=L && count<i)
{
count++;
p = p->next;
}
if(p!=L)
return p;
}
return NULL;
}
/*═════╗
║ 算法2.18 ║
╚═════*/
/* 与课本双链表插入算法略有不同根源在于GetElemP_DuL不同 */
Status ListInsert_DuL(DuLinkList L, int i, LElemType_DC e)
{
DuLinkList p, s;
if(i<1 || i>ListLength_DuL(L)+1) //先对i做出限制
return ERROR;
p = GetElemPtr_DuL(L, i); //确定第i个结点指针
if(!p) //此处若p=NULL说明i = ListLength_DuL(L)+1
p = L; //令p指向头指针
s = (DuLinkList)malloc(sizeof(DuLNode));
if(!s)
exit(OVERFLOW);
s->data = e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return OK;
}
/*═════╗
║ 算法2.19 ║
╚═════*/
Status ListDelete_DuL(DuLinkList L, int i, LElemType_DC *e)
{
DuLinkList p;
if(!(p=GetElemPtr_DuL(L, i))) //i值不合法
return ERROR;
*e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
p = NULL;
return OK;
}
void ListTraverse_DuL(DuLinkList L, void(Visit)(LElemType_DC))
{
DuLinkList p;
p = L->next; //p指向头结点正向访问链表
while(p!=L)
{
Visit(p->data);
p = p->next;
}
}
#endif

View File

@@ -0,0 +1,93 @@
/**********************************************
* *
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
* *
* 文件名: DualCycleLinkedList.h *
* *
* 内 容: 双向循环链表相关操作列表 *
* *
**********************************************/
#ifndef DUALCYCLELINKEDLIST_H
#define DUALCYCLELINKEDLIST_H
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
/* 双循环链表类型定义 */
typedef int LElemType_DC;
typedef struct DuLNode
{
LElemType_DC data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode;
typedef DuLNode* DuLinkList; //指向双循环链表结构的指针
/* 双循环链表函数列表 */
Status InitList_DuL(DuLinkList *L);
/*━━━━━━━━━━┓
┃(01)初始化双链表L。 ┃
┗━━━━━━━━━━*/
Status ClearList_DuL(DuLinkList L);
/*━━━━━━┓
┃(02)置空L。 ┃
┗━━━━━━*/
void DestroyList_DuL(DuLinkList *L);
/*━━━━━━┓
┃(03)销毁L。 ┃
┗━━━━━━*/
Status ListEmpty_DuL(DuLinkList L);
/*━━━━━━━━━━┓
┃(04)判断L是否为空。 ┃
┗━━━━━━━━━━*/
int ListLength_DuL(DuLinkList L);
/*━━━━━━━━━━┓
┃(05)返回L元素个数。 ┃
┗━━━━━━━━━━*/
Status GetElem_DuL(DuLinkList L, int i, LElemType_DC *e);
/*━━━━━━━━━━━━━━━━━┓
┃(06)用e接收L中第i个结点的元素值。 ┃
┗━━━━━━━━━━━━━━━━━*/
int LocateElem_DuL(DuLinkList L, LElemType_DC e, Status (Compare)(LElemType_DC, LElemType_DC));
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(07)返回L中第一个与e满足Compare关系的元素位序。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
Status PriorElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *pre_e);
/*━━━━━━━━━━━━━━┓
┃(08)用pre_e接收cur_e的前驱。┃
┗━━━━━━━━━━━━━━*/
Status NextElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *next_e);
/*━━━━━━━━━━━━━━━┓
┃(09)用next_e接收cur_e的后继。 ┃
┗━━━━━━━━━━━━━━━*/
DuLinkList GetElemPtr_DuL(DuLinkList L, int i);
/*━━━━━━━━━━━━━━━━┓
┃(10)返回L中指向第i个结点的指针。┃
┗━━━━━━━━━━━━━━━━*/
Status ListInsert_DuL(DuLinkList L, int i, LElemType_DC e);
/*━━━━━━━━━━━━━━━━━━━┓
┃(11)算法2.18在L第i个位置之前插入e。 ┃
┗━━━━━━━━━━━━━━━━━━━*/
Status ListDelete_DuL(DuLinkList L, int i, LElemType_DC *e);
/*━━━━━━━━━━━━━━━━━━━━━━━┓
┃(12)算法2.19删除L第i个位置的值并用e接收。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━*/
void ListTraverse_DuL(DuLinkList L, void(Visit)(LElemType_DC));
/*━━━━━━━━━━━┓
┃(13)用Visit函数访问L。┃
┗━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,265 @@
/************************************
* *
* 文件夹: ▲02 线性表 *
* *
* 内 容: 扩展的单链表相关函数测试 *
* *
************************************/
#include <stdio.h>
#include "ExtenLinkedList.c" //**▲02 线性表**//
/* 函数原型 */
Status CmpGreater(LElemType_E e, LElemType_E data); //判断data是否大于e //若data>e返回TRUE
void PrintElem(LElemType_E e); //测试函数,打印整型
int main(int argc, char **argv)
{
ELinkList L;
Link p, q, s;
PositionPtr r;
int i;
LElemType_E e;
printf("▼3\n▲函数 InitList_E 测试...\n"); //3.函数InitList_E测试
{
printf("初始化扩展的单链表 L ...\n");
InitList_E(&L);
printf("\n");
}
PressEnter;
printf("▼14\n▲函数 ListEmpty_E 测试...\n"); //14.函数ListEmpty_E测试
{
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼23\n▲函数 ListInsert_L_E 测试...\n"); //23.函数ListInsert_L_E测试
{
for(i=1; i<=6; i++)
{
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
ListInsert_L_E(&L, i, 2*i);
}
printf("\n");
}
PressEnter;
printf("▼22\n▲函数 ListTraverse_E 测试...\n"); //22.函数ListTraverse_E测试
{
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼15\n▲函数 ListLength_E 测试...\n"); //15.函数ListLength_E测试
{
i = ListLength_E(L);
printf(" L 的长度为 %d \n", i);
printf("\n");
}
PressEnter;
printf("▼24\n▲函数 ListDelete_E 测试...\n"); //24.函数ListDelete_L_E测试
{
ListDelete_L_E(&L, 6, &e);
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼20\n▲函数 LocatePos_E 测试...\n"); //20.函数LocatePos_E测试
{
LocatePos_E(L, 3, &p);
printf(" L 中第 3 个元素 \"%d\" 的地址为 0x%x \n", p->data, p);
printf("\n");
}
PressEnter;
printf("▼18\n▲函数 PriorPos_E 测试...\n"); //18.函数PriorPos_E测试
{
r = PriorPos_E(L, p);
printf("指针 p 指向的元素 \"%d\" 的前驱元素为 \"%d\" \n", p->data, r->data);
printf("\n");
}
PressEnter;
printf("▼19\n▲函数 NextPos_E 测试...\n"); //19.函数NextPos_E测试
{
r = NextPos_E(p);
printf("指针 p 指向的元素 \"%d\" 的后继元素为 \"%d\" \n", p->data, r->data);
printf("\n");
}
PressEnter;
printf("▼21\n▲函数 LocateElem_E 测试...\n"); //21.函数LocateElem_E测试
{
r = LocateElem_E(L, 7, CmpGreater);
printf(" L 中第一个元素值大于 7 的元素 \"%d\" 的地址为 0x%x \n", r->data, r);
printf("\n");
}
PressEnter;
printf("▼1\n▲函数 MakeNode_E 测试...\n"); //1.函数MakeNode_E测试
{
printf("创建结点 p ...\n");
MakeNode_E(&p, 101);
printf("创建结点 q ...\n");
MakeNode_E(&q, 202);
printf("\n");
}
PressEnter;
printf("▼13\n▲函数 GetCurElem_E 测试...\n"); //13.函数GetCurElem_E测试
{
e = GetCurElem_E(p);
printf("结点 p 的值为 \"%d\" \n", e);
e = GetCurElem_E(q);
printf("结点 q 的值为 \"%d\" \n", e);
printf("\n");
}
PressEnter;
printf("▼12\n▲函数 SetCurElem_E 测试...\n"); //12.函数SetCurElem_E测试
{
printf("用 888 替换 p 结点中的值...\n");
SetCurElem_E(p, 888);
printf("结点 p 的值为 \"%d\" \n", p->data);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 FreeNode_E 测试...\n"); //2.函数FreeNode_E测试
{
printf("销毁结点 p 前:");
p ? printf(" p 存在!\n") : printf(" p 不存在!!\n");
FreeNode_E(&p);
printf("销毁结点 p 后:");
p ? printf(" p 存在!\n") : printf(" p 不存在!!\n");
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 Append_E 测试...\n"); //8.函数Append_E测试
{
printf("将 q 结点插在 L 最后一个结点之后...\n");
Append_E(&L, q);
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼9\n▲函数 Remove_E 测试...\n"); //9.函数Remove_E测试
{
printf("删除 L 中最后一个结点,用 p 接收删除的结点...\n");
Remove_E(&L, &p);
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 InsFirst_E 测试...\n"); //6.函数InsFirst_E测试
{
printf("创建值为 303 的结点 p ...\n");
MakeNode_E(&p, 303);
printf("令 q 指向 L 中第 4 个元素...\n");
LocatePos_E(L, 4, &q);
printf("将 p 结点插入到以 q 作头结点的链表的第一个结点之前...\n");
InsFirst_E(&L, q, p);
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼7\n▲函数 DelFirst_E 测试...\n"); //7.函数DelFirst_E测试
{
printf("删除 L 中以第4个结点 q 为头结点的链表的第一个结点...\n");
DelFirst_E(&L, q, &p);
printf("当前 L 的值为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼16\n▲函数 GetHead_E 测试...\n"); //16.函数GetHead_E测试
{
p = GetHead_E(L);
printf(" L 头指针为 p = L.head = 0x%x \n", p);
printf("\n");
}
PressEnter;
printf("▼17\n▲函数 GetLast_E 测试...\n"); //17.函数GetLast_E测试
{
q = GetLast_E(L);
printf(" L 尾指针为 q = L.tail = 0x%x \n", q);
printf("\n");
}
PressEnter;
printf("▼10\n▲函数 InsBefore_E 测试...\n"); //10.函数InsBefore_E测试
{
printf("创建值为 404 的结点 s ...\n");
MakeNode_E(&s, 404);
printf("将结点 s 插入到尾结点 q 之前...\n");
InsBefore(&L, &q, s);
printf("当前 L 的值为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼11\n▲函数 InsAfter_E 测试...\n"); //11.函数InsAfter_E测试
{
printf("创建值为 505 的结点 s ...\n");
MakeNode_E(&s, 505);
printf("将结点 s 插入到头结点 p 之后...\n");
InsAfter(&L, &p, s);
printf(" L 中的元素为L = ");
ListTraverse_E(L, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼4\n▲函数 ClearList_E 测试...\n"); //4.函数ClearList_E测试
{
printf("清空 L 前:");
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
ClearList_E(&L);
printf("清空 L 后:");
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 DestroyList_E 测试...\n"); //5.函数DestroyList_E测试
{
printf("销毁 L 前:");
L.head!=NULL && L.tail!=NULL ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
DestroyList_E(&L);
printf("销毁 L 后:");
L.head!=NULL && L.tail!=NULL ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
Status CmpGreater(LElemType_E e, LElemType_E data)
{
return data>e ? TRUE : FALSE;
}
void PrintElem(LElemType_E e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,306 @@
/*****************************
* *
* 文件夹: ▲02 线性表 *
* *
* 文件名: ExtenLinkedList.c *
* *
* 算 法: 2.20 *
* *
*****************************/
#ifndef EXTENLINKEDLIST_C
#define EXTENLINKEDLIST_C
#include "ExtenLinkedList.h" //**▲02 线性表**//
Status MakeNode_E(Link *p, LElemType_E e)
{
*p = (Link)malloc(sizeof(ELNode)); //申请空间
if(!(*p))
exit(OVERFLOW);
(*p)->data = e;
(*p)->next = NULL;
return OK;
}
void FreeNode_E(Link *p) //释放空间
{
free(*p);
*p = NULL;
}
Status InitList_E(ELinkList *L)
{
Link p;
p = (Link)malloc(sizeof(ELNode));
if(!p)
exit(OVERFLOW);
p->next = NULL;
(*L).head = (*L).tail = p;
(*L).len = 0;
return OK;
}
void ClearList_E(ELinkList *L)
{
Link p, q;
p = (*L).head->next;
while(p)
{
q = p->next;
free(p);
p = q;
}
(*L).head->next = NULL;
(*L).tail = (*L).head;
(*L).len = 0;
}
void DestroyList_E(ELinkList *L)
{
ClearList_E(L);
free((*L).head);
(*L).head = (*L).tail = NULL;
}
void InsFirst_E(ELinkList *L, Link h, Link s)
{
s->next = h->next;
h->next = s;
if(h==(*L).tail) //若h为尾结点
(*L).tail = h->next;
(*L).len++;
}
Status DelFirst_E(ELinkList *L, Link h, Link *q)
{
*q = h->next;
if(*q) //链表非空
{
h->next = (*q)->next;
if(!h->next) //h后只有一个结点
(*L).tail = h;
(*L).len--; //并不释放被删结点所占空间
return OK;
}
return ERROR;
}
void Append_E(ELinkList *L, Link s)
{
int count = 0;
(*L).tail->next = s;
while(s) //考虑s为空的情况
{
(*L).tail = s;
s = s->next;
count++;
}
(*L).len += count;
}
Status Remove_E(ELinkList *L, Link *q)
{
Link p;
if(!(*L).len)
{
*q = NULL;
return ERROR;
}
*q = (*L).tail;
p = (*L).head; //寻找尾结点的前驱
while(p->next!=(*L).tail)
p = p->next;
p->next = NULL;
(*L).tail = p;
(*L).len--;
return OK;
}
void InsBefore(ELinkList *L, Link *p, Link s)
{
Link q;
q = PriorPos_E(*L, *p); //寻找p的前驱
if(!q) //若p无前驱只有一个结点
q = (*L).head;
s->next = *p;
q->next = s;
*p = s;
(*L).len++; //修改len需用到*L
}
void InsAfter(ELinkList *L, Link *p, Link s)
{
if(*p==(*L).tail)
(*L).tail = s;
s->next = (*p)->next;
(*p)->next = s;
*p = s;
(*L).len++;
}
void SetCurElem_E(Link p, LElemType_E e)
{
p->data = e;
}
LElemType_E GetCurElem_E(Link p)
{
return p->data;
}
Status ListEmpty_E(ELinkList L)
{
if(L.len)
return FALSE;
else
return TRUE;
}
int ListLength_E(ELinkList L)
{
return L.len;
}
PositionPtr GetHead_E(ELinkList L)
{
return L.head;
}
PositionPtr GetLast_E(ELinkList L)
{
return L.tail;
}
PositionPtr PriorPos_E(ELinkList L, Link p)
{
Link q;
q = L.head->next;
if(q==p) //首结点无前驱
return NULL;
else
{
while(q->next!=p) //寻找p的前驱
q = q->next;
return q;
}
}
PositionPtr NextPos_E(Link p)
{
return p->next;
}
Status LocatePos_E(ELinkList L, int i, Link *p)
{
int count = 0;
*p = L.head; //i=0时返回头指针
if(i<0 || i>L.len)
return ERROR;
while(count<i)
{
count++;
*p = (*p)->next;
}
return OK;
}
PositionPtr LocateElem_E(ELinkList L, LElemType_E e, Status(Compare)(LElemType_E,LElemType_E))
{
Link p = L.head->next;
while(p && !(Compare(e, p->data)))
p = p->next;
return p;
}
Status ListTraverse_E(ELinkList L, void(Visit)(LElemType_E))
{
Link p;
int j;
p = L.head->next;
for(j=1; j<=L.len; j++)
{
Visit(p->data);
p = p->next;
}
return OK;
}
/*═════╗
║ 算法2.20 ║
╚═════*/
/* 算法2.9的改写 */
Status ListInsert_L_E(ELinkList *L, int i, LElemType_E e)
{
Link h, s;
if(!LocatePos_E(*L, i-1, &h)) //定位第i-1个结点位置
return ERROR; //i值不合法
if(!MakeNode_E(&s, e)) //创建结点
return ERROR; //内存申请失败
InsFirst_E(L, h, s);
return OK;
}
/* 算法2.10的改写,调用了本文档中定义的函数 */
Status ListDelete_L_E(ELinkList *L, int i, LElemType_E *e)
{
Link p, q;
if(i<1 || i>(*L).len)
return ERROR;
LocatePos_E(*L, i-1, &p);
DelFirst_E(L, p, &q);
*e = q->data;
free(q);
q = NULL;
return OK;
}
#endif

View File

@@ -0,0 +1,156 @@
/************************************
* *
* 文件夹: ▲02 线性表 *
* *
* 文件名: ExtenLinkedList.h *
* *
* 内 容: 扩展的单链表相关操作列表 *
* *
************************************/
#ifndef EXTENLINKEDLIST_H
#define EXTENLINKEDLIST_H
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
/* 扩展的单链表类型定义 */
#ifndef POLYNOMIAL_H //在多项式操作中,此类型需重新定义
typedef int LElemType_E;
#endif
typedef struct ELNode //结点类型
{
LElemType_E data;
struct ELNode *next;
}ELNode;
typedef ELNode* Link; //指向结构的指针
typedef ELNode* PositionPtr;
typedef struct //链表类型
{
Link head, tail; //分别指向线性链表中的头结点和尾结点
int len; //指示线性链表中数据元素的个数
}ELinkList;
/* 扩展的单链表函数列表 */
Status MakeNode_E(Link *p, LElemType_E e);
/*━━━━━━━━━━━━┓
┃(01)分配由p指向e的结点。┃
┗━━━━━━━━━━━━*/
void FreeNode_E(Link *p);
/*━━━━━━━━━━━┓
┃(02)释放p指向的结点。 ┃
┗━━━━━━━━━━━*/
Status InitList_E(ELinkList *L);
/*━━━━━━━━━━━━━━┓
┃(03)初始化一个空的线性链表。┃
┗━━━━━━━━━━━━━━*/
void ClearList_E(ELinkList *L);
/*━━━━━━━━━━━━┓
┃(04)重置线性链表L为空。 ┃
┗━━━━━━━━━━━━*/
void DestroyList_E(ELinkList *L);
/*━━━━━━━━━━┓
┃(05)销毁线性链表L。 ┃
┗━━━━━━━━━━*/
void InsFirst_E(ELinkList *L, Link h, Link s);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(06)h指向L中的一个结点将h当做头结点将s插入到“第一个结点”之前。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status DelFirst_E(ELinkList *L, Link h, Link *q);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(07)h指向L中的一个结点将h当做头结点删除“第一个结点”并用q接收。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void Append_E(ELinkList *L, Link s);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(08)将s所指的一串结点链接在L的最后一个结点之后并改变L的尾指针。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status Remove_E(ELinkList *L, Link *q);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(09)删除L的尾结点并用q接收改变尾指针。┃
┗━━━━━━━━━━━━━━━━━━━━*/
void InsBefore_E(ELinkList *L, Link *p, Link s);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(10)将s所指结点插入p所指结点之前,并将p指向新插入的结点。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void InsAfter_E(ELinkList *L, Link *p, Link s);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(11)将s所指结点插入p所指结点之后,并将p指向新插入的结点。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void SetCurElem_E(Link p, LElemType_E e);
/*━━━━━━━━━━━━━━━┓
┃(12)用e更新p指向的结点中的值。┃
┗━━━━━━━━━━━━━━━*/
LElemType_E GetCurElem_E(Link p);
/*━━━━━━━━━━━┓
┃(13)返回p结点中的值。 ┃
┗━━━━━━━━━━━*/
Status ListEmpty_E(ELinkList L);
/*━━━━━┓
┃(14)判空。┃
┗━━━━━*/
int ListLength_E(ELinkList L);
/*━━━━━┓
┃(15)求长。┃
┗━━━━━*/
PositionPtr GetHead_E(ELinkList L);
/*━━━━━━━━━━━━━━━━━┓
┃(16)以指针形式返回L头结点的位置。 ┃
┗━━━━━━━━━━━━━━━━━*/
PositionPtr GetLast_E(ELinkList L);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(17)以指针形式返回L最后一个结点的位置。 ┃
┗━━━━━━━━━━━━━━━━━━━━*/
PositionPtr PriorPos_E(ELinkList L, Link p);
/*━━━━━━━━━━━━━━┓
┃(18)返回p指向的结点的前驱。 ┃
┗━━━━━━━━━━━━━━*/
PositionPtr NextPos_E(Link p);
/*━━━━━━━━━━━━━━┓
┃(19)返回p指向的结点的后继。 ┃
┗━━━━━━━━━━━━━━*/
Status LocatePos_E(ELinkList L, int i, Link *p);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(20)将*p指向L中第i个结点,i=0时为头结点。┃
┗━━━━━━━━━━━━━━━━━━━━*/
PositionPtr LocateElem_E(ELinkList L, LElemType_E e, Status(Compare)(LElemType_E,LElemType_E));
/*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(21)返回L中指向第一个与e满足Compare关系的元素指针。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
Status ListTraverse_E(ELinkList L, void(Visit)(LElemType_E));
/*━━━━━┓
┃(22)访问。┃
┗━━━━━*/
Status ListInsert_L_E(ELinkList *L, int i, LElemType_E e);
/*━━━━━━━━━━━━━━━━━━━┓
┃(23)算法2.20在L第i个位置之前插入e。 ┃
┗━━━━━━━━━━━━━━━━━━━*/
Status ListDelete_L_E(ELinkList *L, int i, LElemType_E *e);
/*━━━━━━━━━━━━━━━━━━┓
┃(24)删除L第i个位置的值并用e接收。 ┃
┗━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,51 @@
/****************************************
* *
* 文件夹: ▲02 线性表\10 MergeEList *
* *
* 内 容: 归并扩展的单链表相关函数测试 *
* *
****************************************/
#include <stdio.h>
#include "MergeEList.c" //**▲02 线性表**//
void PrintElem(LElemType_E e); //测试函数,打印整型
int main(int argc, char **argv)
{
FILE *fp;
ELinkList La, Lb, Lc;
int m, n;
m = 6;
n = 7;
printf("作为示例La长度设定为 %d Lb设定为 %d 创建La和Lb...\n", m, n);
fp = fopen("TestData_La.txt", "r"); //文件指针,指向数据源
CreateList_ascend(fp, &La, m); //创建La与Lb
fclose(fp);
fp = fopen("TestData_Lb.txt", "r"); //文件指针,指向数据源
CreateList_ascend(fp, &Lb, n);
fclose(fp);
printf("La= "); //输出La与Lb
ListTraverse_E(La, PrintElem);
printf("\n");
printf("Lb= ");
ListTraverse_E(Lb, PrintElem);
printf("\n\n");
PressEnter;
MergeEList_L(La, Lb, &Lc, Cmp);
printf("合并La和Lb为 Lc = ");
ListTraverse_E(Lc, PrintElem);
printf("\n\n");
PressEnter;
return 0;
}
void PrintElem(LElemType_E e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,83 @@
/*************************************
* *
* 文件夹: ▲02 线性表\10 MergeEList *
* *
* 文件名: MergeEList.c *
* *
* 算 法: 2.21 *
* *
*************************************/
#ifndef MERGEELIST_C
#define MERGEELIST_C
#include "MergeEList.h" //**▲02 线性表**//
/*═════╗
║ 算法2.21 ║
╚═════*/
Status MergeEList_L(ELinkList La, ELinkList Lb, ELinkList *Lc, int(Compare)(LElemType_E c1, LElemType_E c2))
{
Link ha, hb, pa, pb, q;
LElemType_E c1, c2;
if(!InitList_E(Lc)) //存储分配失败
return ERROR;
ha = GetHead_E(La); //ha指向La头结点
hb = GetHead_E(Lb); //hb指向Lb头结点
pa = NextPos_E(ha); //pa指向La第一个结点
pb = NextPos_E(hb); //pb指向Lb第一个结点
while(!ListEmpty_E(La) && !ListEmpty_E(Lb))
{ //La与Lb非空
c1 = GetCurElem_E(pa); //c1、c2为当前比较的元素
c2 = GetCurElem_E(pb);
if(Compare(c1, c2)<=0)
{
DelFirst_E(&La, ha, &q);
InsFirst_E(Lc, (*Lc).tail, q);
pa = NextPos_E(ha);
}
else
{
DelFirst_E(&Lb, hb, &q);
InsFirst_E(Lc, (*Lc).tail, q);
pb=NextPos_E(hb);
}
}
if(!ListEmpty_E(La))
Append_E(Lc, pa);
else
Append_E(Lc, pb);
FreeNode_E(&ha);
FreeNode_E(&hb);
return OK;
}
int Cmp(LElemType_E c1, LElemType_E c2)
{
return c1-c2;
}
Status CreateList_ascend(FILE *fp, ELinkList *L, int count)
{ //按非降序序列创建链表L
int i;
LElemType_E e;
InitList_E(L);
if(!L)
return ERROR;
for(i=1; i<=count; i++)
{
Scanf(fp, "%d", &e);
ListInsert_L_E(L, i, e);
}
return OK;
}
#endif

View File

@@ -0,0 +1,33 @@
/****************************************
* *
* 文件夹: ▲02 线性表\10 MergeEList *
* *
* 文件名: MergeEList.h *
* *
* 内 容: 归并扩展的单链表相关操作列表 *
* *
****************************************/
#ifndef MERGEELIST_H
#define MERGEELIST_H
#include <stdio.h>
#include "../09 ExtenLinkedList/ExtenLinkedList.c" //**▲02 线性表**//
/* 归并扩展的单链表函数列表 */
Status MergeEList_L(ELinkList La, ELinkList Lb, ELinkList *Lc, int(Compare)(LElemType_E c1, LElemType_E c2));
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.21La与Lb均非递减排列将其归并为一个非递减排列的单链表Lc。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
int Cmp(LElemType_E c1, LElemType_E c2);
/*━━━━━━━━━━━━━━━━┓
┃(02)比较c1、c2大小返回c1-c2。 ┃
┗━━━━━━━━━━━━━━━━*/
Status CreateList_ascend(FILE *fp, ELinkList *L, int count);
/*━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(03)按非降序序列创建元素个数为count的扩展单链表L。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1 @@
La = 1 2 3 5 7 8

View File

@@ -0,0 +1 @@
Lb = 2 4 5 8 10 11 13

View File

@@ -0,0 +1,106 @@
/*************************************
* *
* 文件夹: ▲02 线性表\11 Polynomial *
* *
* 内 容: 一元多项式相关函数测试 *
* *
*************************************/
#include <stdio.h>
#include "Polynomial.c" //**▲02 线性表**//
int main(int argc, char **argv)
{
FILE *fp;
Polynomial Pa, Pb;
int m, n, i;
m = 5;
n = 6;
printf("▼1\n▲函数 CreatPolyn 测试...\n"); //1.函数CreatPolyn测试
{
printf("作为示范,创建项数为 %d 的多项式Pa...\n", m);
fp = fopen("TestData_Pa.txt", "r"); //文件指针,指向数据源
CreatPolyn_P(fp, &Pa, m);
fclose(fp);
printf("作为示范,创建项数为 %d 的多项式Pb...\n", n);
fp = fopen("TestData_Pb.txt", "r");
CreatPolyn_P(fp, &Pb, n);
fclose(fp);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 CreatPolyn 测试...\n"); //8.函数CreatPolyn测试
{
printf("一元多项式 Pa = ");
PrintPolyn_P(Pa);
printf("\n");
printf("一元多项式 Pb = ");
PrintPolyn_P(Pb);
printf("\n\n");
}
PressEnter;
printf("▼3\n▲函数 PolynLength_P 测试...\n"); //3.函数PolynLength_P测试
{
printf(" La 的项数为 %d Lb 的项数为 %d\n", PolynLength_P(Pa), PolynLength_P(Pb));
printf("\n");
}
PressEnter;
printf("▼4、7\n▲函数 AddPolyn_P 等测试...\n"); //4、7.函数AddPolyn_P、Cmp_exp
{
AddPolyn_P(&Pa, &Pb);
printf("Pa = Pa + Pb = ");
PrintPolyn_P(Pa);
printf("\n\n");
}
PressEnter;
printf("▼2\n▲函数DestroyPolyn_P测试...\n"); //2.函数DestroyPolyn_P测试
{
printf("销毁 Pa 前:");
(Pa.head && Pa.tail && Pa.len) ? printf(" Pa 存在!\n") : printf(" Pa 不存在!!\n");
DestroyPolyn_P(&Pa);
printf("销毁 Pa 后:");
(Pa.head && Pa.tail && Pa.len) ? printf(" Pa 存在!\n") : printf(" Pa 不存在!!\n");
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 SubtractPolyn_P 测试...\n"); //5.函数SubtractPolyn_P测试
{
fp = fopen("TestData_Pa.txt", "r");
CreatPolyn_P(fp, &Pa, m);
fclose(fp);
fp = fopen("TestData_Pb.txt", "r");
CreatPolyn_P(fp, &Pb, n);
fclose(fp);
SubtractPolyn_P(&Pa, &Pb);
printf(" Pa = Pa - Pb = ");
PrintPolyn_P(Pa);
DestroyPolyn_P(&Pa);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 MultiplyPolyn_P 测试...\n"); //6.函数MultiplyPolyn_P测试
{
fp = fopen("TestData_Pa.txt", "r");
CreatPolyn_P(fp, &Pa, m);
fclose(fp);
fp = fopen("TestData_Pb.txt", "r");
CreatPolyn_P(fp, &Pb, n);
fclose(fp);
MultiplyPolyn_P(&Pa, &Pb);
printf(" Pa = Pa * Pb = ");
PrintPolyn_P(Pa);
DestroyPolyn_P(&Pa);
printf("\n\n");
}
PressEnter;
return 0;
}

View File

@@ -0,0 +1,275 @@
/*************************************
* *
* 文件夹: ▲02 线性表\11 Polynomial *
* *
* 文件名: Polynomial.c *
* *
* 算 法: 2.22、2.23 *
* *
*************************************/
#ifndef POLYNOMIAL_C
#define POLYNOMIAL_C
#include "Polynomial.h" //**▲02 线性表**//
/*═════╗
║ 算法2.22 ║
╚═════*/
void CreatPolyn_P(FILE *fp, Polynomial *P, int m)
{
PositionPtr h;
ElemType_P e;
int i;
Link p;
InitList_E(P); //初始化一个扩展的单链表存放多项式
h = GetHead_E(*P); //获取多项式头指针
e.coef = 0.0;
e.expn = -1;
SetCurElem_E(h, e); //设置头结点的数据元素
h->next = NULL;
for(i=1; i<=m; i++) //依次录入n个非0项
{
Scanf(fp, "%f%d", &(e.coef), &(e.expn));
MakeNode_E(&p, e);
p->next = NULL;
InsFirst_E(P, h, p);
h = h->next;
}
}
void DestroyPolyn_P(Polynomial *P)
{
DestroyList_E(P);
}
int PolynLength_P(Polynomial P)
{
return ListLength_E(P);
}
/*═════╗
║ 算法2.23 ║
╚═════*/
void AddPolyn_P(Polynomial *Pa, Polynomial *Pb)
{
PositionPtr ha, hb;
PositionPtr qa, qb;
ElemType_P a, b;
float sum;
ha = GetHead_E(*Pa); //ha、hb分别指向Pa、Pb头结点
hb = GetHead_E(*Pb);
qa = NextPos_E(ha); //qa、qb分别指向Pa、Pb的当前结点
qb = NextPos_E(hb);
while(qa && qb) //qa、qb均非空
{
a = GetCurElem_E(qa); //a和b为两表中当前比较元素
b = GetCurElem_E(qb);
switch(Cmp_exp(a,b)) //比较当前元素的指数大小
{
case -1: //多项式Pa中当前结点的指数值较小
ha = qa;
qa = NextPos_E(ha);
break;
case 0: //两者数值相等
sum = a.coef + b.coef;
if(sum != 0.0) //相加不能抵消时更新Pa结点的系数值
{
qa->data.coef = sum;
SetCurElem_E(qa, qa->data);
ha = qa; //此时ha需后移
}
else //相加抵消时删除Pa中当前结点
{
DelFirst_E(Pa, ha, &qa);
FreeNode_E(&qa);
}
DelFirst_E(Pb, hb, &qb); //删除Pb中扫描过的结点
FreeNode_E(&qb);
qb = NextPos_E(hb); //qa、qb均后移
qa = NextPos_E(ha);
break;
case 1: //多项式Pb中当前结点的指数值较小
DelFirst_E(Pb, hb, &qb); //摘下Pb当前结点
InsFirst_E(Pa, ha, qb); //将摘下结点链入Pa中
qb = NextPos_E(hb);
ha = NextPos_E(ha);
break;
}//switch
}//while
if(qb) //若Pb还未扫描完将剩余项链接到Pa后
Append_E(Pa, qb);
FreeNode_E(&hb); //释放Pb头结点
(*Pb).head = (*Pb).tail = NULL; //设置Pb为销毁状态
(*Pb).len = 0;
}
void SubtractPolyn_P(Polynomial *Pa, Polynomial *Pb)
{
PositionPtr ha, hb;
PositionPtr qa, qb;
PositionPtr r;
ElemType_P a, b;
float sum;
ha = GetHead_E(*Pa); //ha、hb分别指向Pa、Pb头结点
hb = GetHead_E(*Pb);
qa = NextPos_E(ha); //qa、qb分别指向Pa、Pb的当前结点
qb = NextPos_E(hb);
while(qa && qb) //qa、qb均非空
{
a = GetCurElem_E(qa); //a和b为两表中当前比较元素
b = GetCurElem_E(qb);
switch(Cmp_exp(a,b)) //比较当前元素的指数大小
{
case -1: //多项式Pa中当前结点的指数值较小
ha = qa;
qa = NextPos_E(ha);
break;
case 0: //两者数值相等
sum = a.coef - b.coef;
if(sum != 0.0) //相减不能抵消时更新Pa结点的系数值
{
qa->data.coef = sum;
SetCurElem_E(qa, qa->data);
ha = qa; //此时ha需后移
}
else //相加抵消时删除Pa中当前结点
{
DelFirst_E(Pa, ha, &qa);
FreeNode_E(&qa);
}
DelFirst_E(Pb, hb, &qb); //删除Pb中扫描过的结点
FreeNode_E(&qb);
qb = NextPos_E(hb); //qa、qb均后移
qa = NextPos_E(ha);
break;
case 1: //多项式Pb中当前结点的指数值较小
DelFirst_E(Pb, hb, &qb); //摘下Pb当前结点
qb->data.coef = - qb->data.coef; //改变当前结点符号
InsFirst_E(Pa, ha, qb); //将摘下结点链入Pa中
qb = NextPos_E(hb);
ha = NextPos_E(ha);
break;
}//switch
}//while
if(qb) //Pb还未扫描完
{
r = qb;
while(r)
{
r->data.coef = - r->data.coef; //改变剩余结点符号
r = r->next;
}
Append_E(Pa, qb);
}
FreeNode_E(&hb); //释放Pb头结点
(*Pb).head = (*Pb).tail = NULL;
(*Pb).len = 0;
}
void MultiplyPolyn_P(Polynomial *Pa, Polynomial *Pb)
{
Polynomial Pc, Ptmp;
int i, j, la, lb;
PositionPtr ha;
PositionPtr qa, qb;
Link s;
la = PolynLength_P(*Pa);
lb = PolynLength_P(*Pb);
ha = (*Pa).head;
InitList_E(&Pc);
for(i=1; i<=la; i++)
{
InitList_E(&Ptmp);
DelFirst_E(Pa, ha, &qa);
qb = (*Pb).head->next;
for(j=1; j<=lb; j++)
{
s = (Link)malloc(sizeof(ELNode)); //申请空间
if(!s)
exit(OVERFLOW);
s->data.coef = qa->data.coef * qb->data.coef; //系数相乘
s->data.expn = qa->data.expn + qb->data.expn; //指数相加
s->next = NULL;
Append_E(&Ptmp, s);
qb = qb->next;
}
AddPolyn_P(&Pc, &Ptmp);
}
AddPolyn_P(Pa, &Pc);
DestroyPolyn_P(Pb);
}
int Cmp_exp(ElemType_P c1, ElemType_P c2)
{
int i = c1.expn - c2.expn;
if(i<0)
return -1;
else if(i==0)
return 0;
else
return 1;
}
void PrintPolyn_P(Polynomial P)
{
int i;
Link p;
p = P.head->next;
for(i=1; i<=P.len; i++)
{
if(i==1)
printf("%g", p->data.coef);
else
{
if(p->data.coef>0)
{
printf(" + ");
printf("%g", p->data.coef);
}
else
{
printf(" - ");
printf("%g", -p->data.coef);
}
}
if(p->data.expn)
{
printf("x");
if(p->data.expn!=1)
printf("^%d", p->data.expn);
}
p = p->next;
}
}
#endif

View File

@@ -0,0 +1,68 @@
/*************************************
* *
* 文件夹: ▲02 线性表\11 Polynomial *
* *
* 文件名: Polynomial.h *
* *
* 内 容: 一元多项式相关操作列表 *
* *
*************************************/
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
/* 多项式类型定义 */
typedef struct //用来表示多项式的项
{
float coef; //系数
int expn; //指数
}LElemType_E; //重新定义扩展的线性表中元素类型
#include "../09 ExtenLinkedList/ExtenLinkedList.c"//**▲02 线性表**//
typedef LElemType_E ElemType_P; //一元多项式项的类型
typedef ELinkList Polynomial; //一元多项式
/* 一元多项式函数列表 */
void CreatPolyn_P(FILE *fp, Polynomial *P, int m);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(01)算法2.22创建项数为m的一元多项式。 ┃
┗━━━━━━━━━━━━━━━━━━━━*/
void DestroyPolyn_P(Polynomial *P);
/*━━━━━━━━━━┓
┃(02)销毁一元多项式。┃
┗━━━━━━━━━━*/
int PolynLength_P(Polynomial P);
/*━━━━━━━━━━━━━┓
┃(03)返回一元多项式的项数。┃
┗━━━━━━━━━━━━━*/
void AddPolyn_P(Polynomial *Pa, Polynomial *Pb);
/*━━━━━━━━━━━━━━━━━━━━━━━┓
┃(04)算法2.23一元多项式加法Pa=Pa+Pb销毁Pb。┃
┗━━━━━━━━━━━━━━━━━━━━━━━*/
void SubtractPolyn_P(Polynomial *Pa, Polynomial *Pb);
/*━━━━━━━━━━━━━━━━━━┓
┃(05)一元多项式减法Pa=Pa-Pb销毁Pb。┃
┗━━━━━━━━━━━━━━━━━━*/
void MultiplyPolyn_P(Polynomial *Pa, Polynomial *Pb);
/*━━━━━━━━━━━━━━━━━━┓
┃(06)一元多项式乘法Pa=Pa*Pb销毁Pb。┃
┗━━━━━━━━━━━━━━━━━━*/
int Cmp_exp(ElemType_P c1, ElemType_P c2);
/*━━━━━━━━━━━━━━┓
┃(07)比较c1项和c2项指数大小。┃
┗━━━━━━━━━━━━━━*/
void PrintPolyn_P(Polynomial P);
/*━━━━━━━━━━━━┓
┃(08)打印输出一元多项式。┃
┗━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1 @@
Pa = (2.1 , 1) (4.0 , 3) (-3.12 , 5) (5.3 , 7) (2.5 , 9)

View File

@@ -0,0 +1 @@
Pb = (3.4 , 2) (-3.17 , 4) (4.1 , 5) (1.8 , 8) (-2.5 , 9) (0.5 , 12)