严蔚敏《数据结构(C语言版)》第二章 纯C实现

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

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define ElemType int
#define ERROR 1

typedef struct
{
	ElemType *elem;
	int Length;
}SqList;

void InitList(SqList *L)
{
	L->elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
	if(!L->elem)
	{
		exit(ERROR);
	}
	L->Length = 0;
	return;
}

void ListInsert(SqList *L, int i, ElemType e)
{
	printf("在第%d位插入%d\n\n", i, e);
	if(i<=0 || i > MAXSIZE)
	{
		exit(ERROR);
	}
	if(L->Length == MAXSIZE)
	{
		exit(ERROR);
	}
	for(int j=(L->Length) - 1;j >= i-1 ;j--)
	{
		L->elem[j+1] = L->elem[j];
	}
	L->elem[i-1] = e;
	++ L->Length;
	return;
}

void GetElem(SqList L, int i, ElemType *e)
{
	if(i<=0 || i > L.Length)
	{
		exit(ERROR);
	}
	else 
	*e = L.elem[i-1];
	return;
}

int LocateElem(SqList L, ElemType e)
{
	for(int i=0;i<=L.Length;i++)
	{
		if(L.elem[i] == e)
		{
			return (i+1);
		}
	}
	return 0;
}

void ListDelete(SqList *L, int i)
{
	printf("删除第%d位元素\n\n", i);
	if(i<=0 || i > L->Length)
	{
		exit(ERROR);
	}
	for(int j=0;i<=L->Length - 1;j++)
	{
		L->elem[j-1] = L->elem[j];
	}
	--L->Length;
	return;
}

void DestroyList(SqList *L)
{
	if(L->elem)
	{
		free(L->elem);
		L->Length = 0;
		printf("储存空间已释放\n\n");
	}
	return;
}

void ShowList(SqList L)
{
	printf("线性表长度:%d\n", L.Length);
	if(L.Length > 0)
	{
		printf("线性表为:");
		for(int i=0;i<L.Length;i++)
		{
			printf("%d ", L.elem[i]);
		}
		printf("\n");
	}
	printf("\n");
}

int main(void)
{
	SqList L;
	
	InitList(&L);
	ShowList(L);
	ListInsert(&L, 1, 4);
	ShowList(L);
	ListInsert(&L, 1, 3);
	ShowList(L);
	/*
	ElemType *e;
	e = (ElemType *)malloc(sizeof(ElemType));
	GetElem(L, 4, e);
	printf("现在线性表第%d元素为%d.\n", 4, *e);
	*/
	printf("%d是线性表第%d位元素\n\n", 4, LocateElem(L, 4));
	ListDelete(&L, 2);
	ShowList(L);
	DestroyList(&L);
	return 0;
}

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

单向链表

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define ElemType char
#define ERROR 1

typedef struct LNode
{
	ElemType data;
	struct LNode *Next;
}LNode, *LinkList;



void InitList(LinkList *L)
{
	*L = (LNode *)malloc(sizeof(LNode));
	(*L)->Next = NULL;
	printf("初始化成功");
	return;
}

void CreateList_H(LinkList *L, int n)
{
	*L = (LNode *)malloc(sizeof(LNode));
	(*L)->Next = NULL;
	LinkList  p;
	for(int i = 0; i < n; i++)
	{
		char temp;
		p = (LNode *)malloc(sizeof(LNode));
		printf("请输入第%d个节点数据:", i+1);
		p->data = getchar();
		temp = getchar();
		p->Next = (*L)->Next;
		(*L)->Next = p;
	}
	return;
}

void CreateList_R(LinkList *L, int n)
{
	*L = (LNode *)malloc(sizeof(LNode));
	(*L)->Next = NULL;
	LinkList  p, r = *L;
	for(int i = 0; i < n; i++)
	{
		char temp;
		p = (LNode *)malloc(sizeof(LNode));
		printf("请输入第%d个节点数据:", i+1);
		p->data = getchar();
		temp = getchar();
		p->Next = NULL;
		r->Next = p;
		r = p;
	}
	return;
}

void ListInsert(LinkList *L, int i, ElemType e)
{
	LinkList s, p = *L;
	int j = 0;
	while(p && (j<i-1))
	{
		p = p->Next;
		j++;
	}
	if(!p || j>i+1)
	{
		exit(1);
	}
	s = (LNode *)malloc(sizeof(LNode));
	s->data = e;
	s->Next = p->Next;
	p->Next = s;
	printf("在链表的第%d位置成功插入%c\n", i, e);
	return;
}

void GetElem(LinkList L, int i, ElemType *e)
{
	LinkList p = L->Next;
	int j = 1;
	while(p && j<i)
	{
		p = p->Next;
		j++;
	}
	if(!p || j>i)
	{
		exit(1);
	}
	*e = p->data;
	return;
}

LNode *LocateElem(LinkList L, ElemType e)
{
	LinkList p = L->Next;//p指向首元结点
	int j = 1;
	while(p && p->data != e)
	{
		j++;
		p = p->Next;
	}
	printf("%c在链表的%d号位置\n",e, j);
	return p;
}

ElemType GetElem_V(LinkList L, int i)
{
	LinkList p = L->Next;
	int j = 1;
	while(p && j<i)
	{
		p = p->Next;
		j++;
	}
	if(!p || j>i)
	{
		exit(1);
	}
	return (p->data);
}

void ListDelete(LinkList *L, int i)
{
	LinkList p = *L;
	int j = 1;
	while((p->Next) && (j<i-1))		//定位到第i号元素
	{
		p = p->Next;
		j++;
	}
	if(!p || j>i)
	{
		exit(1);
	}
	LinkList q = p->Next;
	p->Next = q->Next;
	free(q);
	printf("链表的%d号位置已删除\n",j);
	return 0;
}

int main(void)
{
	LinkList L, p;
	ElemType e;
	
	CreateList_R(&L, 4);
	GetElem(L, 1, &e);
	printf("第一个元素是%c\n", e);
	
	ListInsert(&L, 1, 'a');
	printf("第一个元素是%c\n", GetElem_V(L, 1));
	
	LocateElem(L, 'q');
	ListDelete(&L, 1);
	printf("第一个元素是%c\n", GetElem_V(L, 1));
	
	return 0;
	
}

双向链表

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define ElemType char
#define ERROR 1

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


void CreateList_R(DuLinkList *L, int n)
{
	*L = (DuLNode *)malloc(sizeof(DuLNode));
	(*L)->next = NULL;
	(*L)->prior = NULL;
	DuLinkList  p, r = *L;
	for(int i = 0; i < n; i++)
	{
		char temp;
		p = (DuLNode *)malloc(sizeof(DuLNode));
		printf("请输入第%d个节点数据:", i+1);
		p->data = getchar();
		temp = getchar();
		p->next = NULL;
		r->next = p;
		p->prior = r;
		r = p;
	}
	r->next = *L;
	return;
}


void ListInsert(DuLinkList *L, int i, ElemType e)
{
	DuLinkList s, p = *L;
	int j = 0;
	while(p && (j<i-1))
	{
		p = p->next;
		j++;
	}
	if(!p || j>i+1)
	{
		exit(1);
	}
	s = (DuLNode *)malloc(sizeof(DuLNode));
	s->data = e;
	s->next = p->next;
	p->next->prior = s;
	p->next = s;
	s->prior = p;
	printf("在链表的第%d位置成功插入%c\n", i, e);
	return;
}


void ListDelete(DuLinkList *L, int i)
{
	DuLinkList p = *L;
	int j = 1;
	while((p->next) && (j<i-1))		//定位到第i-1号元素
	{
		p = p->next;
		j++;
	}
	if(!p || j>i)
	{
		exit(1);
	}
	DuLinkList q = p->next;
	p->next = q->next;
	q->next->prior  = p;
	free(q);
	printf("链表的%d号位置已删除\n",j);
	return;
	
}

void ShowList(DuLinkList L)
{
	DuLinkList p = L->next;
	int i = 1;
	do{
		printf("第%d号节点元素是%c\n", i, p->data);
		p = p->next;
		i++;
	}while((p) != NULL);
	
	return;
	
}

2.7线性表的应用

线性表的合并

void MergeList(SqList *LA, SqList LB)
{
	int m = (*LA).Length, n = LB.Length;
	ElemType e;
	for(int i = 1;i <= n; i++)
	{
		GetElem(LB, i, &e);
		if(!LocateElem((*LA), e))
		{
			ListInsert(LA, ++m, e);
		}
	}
	return;
}

顺序有序表的合并

void MergeList_Sq(SqList LA, SqList LB, SqList *LC)
{
	LC->Length = LA.Length + LB.Length;
	LC->elem = (ElemType *)malloc(LC->Length * sizeof(ElemType));
	ElemType *pa = LA.elem, *pb = LB.elem, *pc = LC->elem;
	ElemType *pa_last = LA.elem + LA.Length - 1;
	ElemType *pb_last = LB.elem + LB.Length - 1;
	
	while((pa <= pa_last) && (pb <= pb_last))
	{
		if(*pa <= *pb)
		{
			*pc++ = *pa++;		//建议写成pc = pa; pc++; pa++;程序是人的语言而不是机器的语言
		}
		else
		{
			*pc++ = *pb++;
		}
	}
	
	while(pa <= pa_last)
	{
		*pc++ = *pa++;
	}
	
	while(pb <= pb_last)
	{
		*pc++ = *pb++;
	}
}

顺序链表的归并

void MergeList_L(LinkList *LA, LinkList *LB, LinkList *LC)		//按序合并链表
{
	LinkList pa = (*LA)->Next;
	LinkList pb = (*LB)->Next;
	*LC = *LA;
	LinkList pc = (*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);
}

void MergeList_Test(void)
{
	printf("链表的归并测试\n\n");
	LinkList LA, LB, LC;
	CreateList_R(&LA, 3);
	ShowList(LA);
	CreateList_R(&LB, 4);
	ShowList(LB);
	MergeList_L(&LA, &LB, &LC);
	ShowList(LC);
	return;
}

2.8 案例分析与实现

#include<stdio.h>
#include<stdlib.h>


typedef struct PNode
{
	float coef;		//系数
	int expn;			//指数
	struct PNode *next;
}PNode, *polynomial;

//多项式的创建
void CreatePoly(polynomial *P, int n)
{
	*P = (PNode *)malloc(sizeof(PNode));
	(*P)->next = NULL;
	for(int i = 1;i <= n; i++)
	{
		polynomial s;
		s = (PNode *)malloc(sizeof(PNode));
		printf("请输入第%d项多项式的系数和指数,用半角逗号隔开:", i);
		scanf("%f,%d", &(s->coef), &(s->expn));
		polynomial pre = *P;
		polynomial q = (*P)->next;
		while(q && q->expn<s->expn)		//定位到要插入的前一位
		{
			pre = q;
			q = q->next;
		}
		s->next = q;					//插入
		pre->next = s;
	}
}

void ShowPoly(polynomial P)
{
	polynomial pp = P->next;
	int i = 1;
	while(pp)
	{
		printf("第%d项:系数为%.2f,指数为%d\n", i, pp->coef, pp->expn);
		pp = pp->next;
		i++;
	}
	return;
}

void AddPolyn(polynomial *Pa, polynomial *Pb)
{
	polynomial p1 = (*Pa)->next;
	polynomial p2 = (*Pb)->next;
	polynomial p3 = Pa;
	while(p1 && p2)
	{
		if(p1->expn == p2->expn)		//指数相同,做相加工作
		{
			float sum = p1->coef + p2->coef;
			if(sum)						//若两系数之和不为0
			{
				p1->coef = sum;
				p3->next = p1;
				p1 = p1->next;
				polynomial r = p2;
				p2 = p2->next;
				free(r);
			}
			else
			{
				polynomial r = p1;
				p1 = p1->next;
				free(r);				
				r = p2;
				p2 = p2->next;
				free(r);
			}
		}
		else if(p1->expn < p2->expn)
		{
			p3->next = p1;
			p3 = p1;
			p1 = p1->next;
		}
		else
		{
			p3->next = p2;
			p3 = p2;
			p2 = p2->next;
		}
	}
	p3->next = p1 ? p1 : p2;
	free(*Pb);
}

int main(void)
{
	polynomial test1_P, test2_P;
	CreatePoly(&test1_P, 4);
	ShowPoly(test1_P);
	CreatePoly(&test2_P, 3);
	ShowPoly(test2_P);
	AddPolyn(&test1_P, &test2_P);
	ShowPoly(test1_P);
	return 0;
}

算法设计题

以下均在对应位置测试过

(1)

void MergeList_L(LinkList *LA, LinkList *LB, LinkList *LC)		//按序合并链表
{
	LinkList pa = (*LA)->Next;
	LinkList pb = (*LB)->Next;
	*LC = *LA;
	LinkList pc = (*LC);
	while(pa && pb)
	{
		if(pa->data < pb->data)
		{
			pc->Next = pa;
			pc = pa;
			pa = pa->Next;
		}
		else if(pa->data > pb->data)
		{
			pc->Next = pb; 
			pc = pb;
			pb = pb->Next;
		}
		else
		{
			pc->Next = pb; 
			pc = pb;
			pb = pb->Next;
			LinkList r = pa;
			pa = pa->Next;
			free(r);
		}
	}
	pc->Next = pa ? pa : pb;
	free(*LB);
}

(2)

(3)

void InterList_L(LinkList *LA, LinkList *LB, LinkList *LC)		//求交集
{
	LinkList pa = (*LA)->Next;
	LinkList pb = (*LB)->Next;
	*LC = *LA;
	LinkList pc = (*LC);
	while(pa && pb)
	{
		if(pa->data == pb->data)		//如果两链表值相等,储存在A中
		{
			pc->Next = pa;
			pc = pa;
			pa = pa->Next;
			LinkList r = pb;
			pb = pb->Next;
			free(r);
		}
		else
		{
			LinkList r = pa;
			pa = pa->Next;
			free(r);
		}
	}
	pc->Next = NULL;
	while(pb)
	{
		LinkList r = pb;
		pb = pb->Next;
		free(r);
	}
	free(*LB);
}

void InterList_Test(void)
{
	printf("链表的交集测试\n\n");
	LinkList LA, LB, LC;
	CreateList_R(&LA, 5);
	ShowList(LA);
	CreateList_R(&LB, 4);
	ShowList(LB);
	InterList_L(&LA, &LB, &LC);
	ShowList(LC);
	return;
}

(5)

按照大于d,小于d对长链表进行分解(之前我的链表是储存字符的,懒得改了)

void UnpackList(LinkList *LA, LinkList *LB, LinkList *LC) 		//分解链表,以字母d为界
{
	LinkList pa = (*LA)->Next;
	LinkList pb = *LB, pc = *LC;
	
	while(pa)
	{
		if(pa->data < 'd')
		{
			pb->Next = pa;
			pb = pa;
			pa = pa->Next;
		}
		else if(pa->data > 'd')
		{
			pc->Next = pa;
			pc = pa;
			pa = pa->Next;
		}
		else
		{
			LinkList r = pa;
			pa = pa->Next;
			free(r);
		}
	}
	pb->Next = NULL;
	pc->Next = NULL;
	free(*LA);
}

void UnpackList_Test(void)
{
	printf("链表的分解测试\n\n");
	LinkList LA, LB, LC;
	CreateList_R(&LA, 10);
	ShowList(LA);
	InitList(&LB);
	InitList(&LC);
	UnpackList(&LA, &LB, &LC);
	ShowList(LB);
	ShowList(LC);
	return;
}

(10)

这个暂时还有点问题,时间复杂度好像不是O(n),后面看情况再改。

void ListDelete_Item(SqList *L, ElemType e)
{
	int size = L->Length;
	for(int i = size - 1;i >= 0; i--)
	{
		if(L->elem[i] == e)
		{
			for(int j = i;j < L->Length; j++)
			{
				L->elem[j] = L->elem[j + 1];
			}
			L->Length--;
		}
	}
	
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值