链式存储结构的基本操作

(一)单链表的定义及基本操作
(1)用带表头的链表存放输入的数据,每读入一个数,按升序顺序插入到链表中,链表中允许两个结点有相同值。链表的头结点存放链表后面的结点个数,初始化时就生成头结点(初值为0)。
(2)在上述带表头的链表中删除第i个结点或删除数值为item的结点。
(3)链表翻转是把数据逆序(变成降序),注意,头结点不动。翻转后要再翻转一次,恢复升序后才能插入新元素,否则会出错。
(4)设A与B分别为两个带有头结点的有序循环链表(所谓有序是指链接点按数据域值大小链接,本题不妨设按数据域值从小到大排列),list1和list2分别为指向两个链表的指针。请写出并在计算机上实现将这两个链表合并为一个带头结点的有序循环链表的算法。
(二)链式堆栈的定义及基本操作
(5)先定义堆栈的几个基本操作,再设计一主函数利用堆栈的操作完成以下功能:假设一个算术表达式中可以包含三种括号:()[]{},且这三种括号可以按任意次序嵌套使用(如:…[…{…}…[…]…]…(…))。编写判别给定表达式中所含括号是否正确配对出现的算法,已知表达式已存入数据元素为字符的单链表中。
(三)链式队列的定义及基本操作
(6)先定义队列的几个基本操作,再设计一主函数利用队列的操作完成以下功能:键盘输入的字符可以临时存入键盘的缓冲区中。为了充分利用缓冲区的空间,往往将缓冲区设计成链式循环队列的结构,并为循环队列结构的缓冲区设置一个队首指针和一个队尾指针。每输入一个字符到缓冲区中,就将尾指针后移,链入缓冲区的循环队列之中;每输出一个字符号,就将队头指针前移,将它从缓冲队列中删除。假设有两个进程同时存在于一个应用程序中,第一个进程连续在屏幕上显示字符“X”,第二个进程不断查键盘上是否有输入,若有则读入用户键入的字符,将其保存到键盘缓冲区中。
实验过程原始数据记录
main.cpp
#include"List.h"
#include"Stack.h"
#include"Queue.h"
#include"conio.h"

#include <thread>

void main()
{

List A,list1,list2,B,S;

InitList(A);
cout << "1.输入5个数,升序插入链表:" << '\n';
CreateListSort(A, 5);
DisplayList(A);
cout << "2.删除第2个结点:" << '\n';
ElemType e;
ListDelete(A, 2, e);
DisplayList(A);
cout << "2.删除数值5的结点:" << '\n';
DeleteElem(A, 5);
DisplayList(A);
cout << "3.链表逆序:" << '\n';
ListInverse(A);
DisplayList(A);
cout << "输入2个长度5的链表:" << '\n';
CreateOrderedCyclicList(list1, 5);
DisplayList(list1);
CreateOrderedCyclicList(list2, 5);
DisplayList(list2);
cout << "4.合并成有序循环链表:" << '\n';
MergeOrderedListC(list1, list2, B);
DisplayList(B);

cout << "5.输入一组括号:" << '\n';
string exp;
cin >> exp;
	InitList(S);
	int i = 1;
	for (i; i <= exp.length(); i++)
	{
    	ListInsert(S, i, exp[i-1]);		
	}	
DisplayList(S);
if(!matching(S))
	cout<<"括号匹配失败"<<'\n';
else
	cout << "括号匹配成功" << '\n';

cout << "6.双线程缓冲区:" << '\n';

Queue Q;
InitQueue(Q);
thread thread1(en,ref(Q));
thread thread2(out,ref(Q));
thread1.join();
thread2.join();

};

List.h
#pragma once

#include<iostream>

using namespace std;

typedef char ElemType;

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

bool InitList(List &L);

void DestroyList(List &L);

void ClearList(List &L);

bool GetElem(List L, int i, ElemType &e);

int LocateElem(List L, ElemType e);

bool ListInsert(List &L, int i, ElemType e);

bool ListInsertSort(List &L, ElemType e);

bool ListDelete(List &L, int i, ElemType &e);

bool DeleteElem(List &L, ElemType e);

int ListLength(List L);

bool ListEmpty(List L);

bool DisplayList(List L);

void CreateList(List &L, int n);

void CreateListSort(List &L, int n);

void MergeList(List LA, List LB, List &LC);

void SectionList(List LA, List LB, List &LC);

void SubtractList(List LA, List LB, List &LC);

void ListInverse(List &L);

void CreateOrderedCyclicList(List &L, int n);

void MergeOrderedListC(List LA, List LB, List &LC);

List.cpp

#include"List.h"
//初始化链表L,生成头节点存放链表后面的结点个数
bool InitList(List &L)
{
L = new LNode;
if (!L) return false;
L->next = NULL;
L->data = 0;//节点数
return true;
} // InitList

void DestroyList(List &L)
{
// 销毁以L为头指针的单链表,释放链表中所有结点空间
List p;
while (L)
{
p = L;
L = L->next;
delete§;
} // while
L = NULL;
cout << “此链表已摧毁” << ‘\n’;
} // DestroyList

void ClearList(List &L)
{
ElemType e;
int n = ListLength(L);
while (n–)
{
ListDelete(L, 1, e);
}
}

bool GetElem(List L, int i, ElemType &e)
{
// 若1≤i≤LengthList(L),则用 e 带回指针L指向头结点的单链表
// 中第 i 个元素的值且返回函数值为TRUE,否则返回函数值为FALS
List p;
p = L->next; int j = 1;
while (p && j < i)
{
p = p->next; ++j;
}
if (!p || j > i) return false;
e = p->data;
return true;
}

int LocateElem(List L, ElemType e)
{
int i = 0;
ElemType s;
for (i = 1; i <= ListLength(L); i++)
{
GetElem(L, i, s);
if (s == e)
{
return i;
}
}
return false;
}
//插入e到升序链表L
bool ListInsertSort(List &L, ElemType e)
{

List p, s;
p = L;
while ((p->next) && (e > (p->next->data)))
{
	p = p->next;
}
s = new LNode;
if (!s) return false;
(L->data)++;
s->data = e;
s->next = p->next; p->next = s;
return true;

}
//插入e到链表L第i个结点后
bool ListInsert(List &L, int i, ElemType e)
{
List p, s;
p = L; int j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if (!p || j > i - 1) return false;
s = new LNode;
if (!s) return false;
(L->data)++;
s->data = e;
s->next = p->next; p->next = s;
return true;
}
//删除链表L第i个结点,以e带回被删除的数值
bool ListDelete(List &L, int i, ElemType &e)
{

 // 若1≤i≤LengthList(L),则删除指针L指向头结点的单链表
// 中第 i 个元素并以 e 带回其值,返回函数值为 TRUE,
// 否则不进行删除操作且返回函数值为 FALSE
List p, q;
p = L; int j = 0;
while (p->next && j < i - 1)
{
	p = p->next; ++j;
}
if (!(p->next) || j > i - 1) return false;
q = p->next;
e = q->data;
p->next = q->next;
delete q;
(L->data)--;
return true;

} // ListDelete_L
//删除链表L中数值是e的结点
bool DeleteElem(List &L, ElemType e)
{
//ElemType s;
//ListDelete(L, LocateElem(L, e), s);
//return true;
int i = 0;
ElemType s;
for (i = 1; i <= ListLength(L); i++)
{
GetElem(L, i, s);
if (s == e)
{
ListDelete(L, i, s);
i–;
}
}
return 1;
}

int ListLength(List L)

{

int len = 0;

List P = L;

while (P != nullptr)

{

	P = P->next;

	++len;
}
return --len;

}

bool ListEmpty(List L)
{
if (L->next == NULL)
{
return true;
}
else if (L->next != NULL)
{
return false;
}

}

bool DisplayList(List L)

{
if (L == NULL)
{
cout << “此链表不存在” << ‘\n’;
return 0;
}
cout << “此链表长度为” << int(L->data);
List list = L->next;
if (list == NULL)
{
cout << “此链表为空” << ‘\n’;
return 0;
}
cout << ": ";
int i=0;
while (list != NULL&&i<(L->data))

{
cout << list->data << " ";
list = list->next;
i++;

}
cout << ‘\n’;
return 1;
}
//按输入顺序创建长度n的链表L
void CreateList(List &L, int n)
{
InitList(L);
ElemType e;
int i = 1;
for (i; i <= n; i++)
{
cin >> e;
if (!LocateElem(L, e))
{
ListInsert(L, i, e);
}
}
}
//创建一个长度n的升序链表L
void CreateListSort(List &L, int n)
{

InitList(L);
ElemType e;
int i = 1;
for (i; i <= n; i++)
 {
	cin >> e;
	ListInsertSort(L, e);
 }

}

void MergeList(List LA, List LB, List &LC)
{
int lenc, i;
ElemType e;
InitList(LC);
for (i = 1; i <= ListLength(LA); i++) //将LA的所有元素插入到Lc中
{
GetElem(LA, i, e);
ListInsert(LC, i, e);
}
lenc = ListLength(LA); //求线性表LA的长度
for (i = 1; i <= ListLength(LB); i++)
{
GetElem(LB, i, e); //取LB中第i个数据元素赋给e
if (!LocateElem(LA, e)) //LA中不存在和e相同者,插入到LC中
ListInsert(LC, ++lenc, e);
}
}

void SectionList(List LA, List LB, List &LC)
{
InitList(LC);
int lenc = 0, i;
ElemType e;
for (i = 1; i <= ListLength(LA); i++)
{
GetElem(LA, i, e);
if (LocateElem(LB, e))
{
ListInsert(LC, ++lenc, e);
}
}
}

void SubtractList(List LA, List LB, List &LC)
{
InitList(LC);
int lenc = 0, i;
ElemType e;

for (i = 1; i <= ListLength(LA); i++)
{
	GetElem(LA, i, e);
	if (!LocateElem(LB, e))
	{
		ListInsert(LC, ++lenc, e);
	}

}

}
//链表L逆序
void ListInverse(List &L)
{
List N, P,H;
P = NULL; H = L;
L = L->next;
while(L)
{
N = L->next;
L->next = P;
P = L;
L = N;
}
H->next = P;
L = H;
}

void CreateOrderedCyclicList(List &L, int n)
{
InitList(L);
ElemType e;
int i = 1;
for (i; i <= n; i++)
{
cin >> e;
ListInsertSort(L, e);
}
List P = L;
while (P->next)
{
P =P->next;
}
P->next = L->next;
}

void MergeOrderedListC(List LA, List LB, List &LC)
{
int i;
ElemType e;
InitList(LC);
for (i = 1; i <= LA->data; i++) //将LA的所有元素插入到Lc中
{
GetElem(LA, i, e);
ListInsertSort(LC, e);
}
for (i = 1; i <= LB->data; i++)
{
GetElem(LB, i, e); //取LB中第i个数据元素赋给e
//if (!LocateElem(LA, e)) //LA中不存在和e相同者,插入到LC中
ListInsertSort(LC, e);
}
List P = LC;
while (P->next)
{
P = P->next;
}
P->next = LC->next;
}

Stack.h

#pragma once
#include
#include
#include"List.h"
using namespace std;
typedef char ElemType;

typedef struct Node
{
ElemType data;
struct Node *next;

}*Stack;

bool InitStack(Stack &S);

bool StackEmpty(Stack S);

int StackLength(Stack S);

bool Push(Stack &S, ElemType e);

bool Pop(Stack &S, ElemType &e);

bool GetTop(Stack S, ElemType &e);

bool matching(List &exp);

Stack.cpp
#include"Stack.h"

bool InitStack(Stack &S)
{
S = NULL;
return true;
}
bool StackEmpty(Stack S)
{
if (S == NULL) return true; //
else return false;
}
int StackLength(Stack S)
{
Stack p;
int i = 0;
for (p = S; p != NULL; p = p->next, i++);
return i;
}
bool Push(Stack &S, ElemType e)
{
Stack p = new Node;
if (!p) return false;
p->data = e;
p->next = S;
S = p;
return true;
}
bool Pop(Stack &S, ElemType &e)
{
// 若栈不空,则删除S的栈顶元素,
// 用 e 返回其值,并返回true;
// 否则返回false
Stack p;
if (S == NULL) return false;
e = S->data;
p = S; S = S->next;
delete p;
return true;
}
bool GetTop(Stack S, ElemType &e)
{
// 若栈不空,返回S的栈顶元素给e,
// 否则返回false
if (S == NULL) return false;
e = S->data;
return true;
}

bool matching(List &exp)
{

Stack S;
InitStack(S);
bool state = 1;
int i=0;
ElemType e;
exp = exp->next;
while (exp && state)
{

	int f = 0;
	if (f) break;//输入出错,终止循环
	switch (exp->data)
	{

	 default:f = 1; state = 0;//输入出错
	 case '(':
	     
		 Push(S, exp->data); exp= exp->next;

	 break;

	 case  '[':

		 Push(S, exp->data); exp = exp->next;

		 break;

	 case  '{':

		 Push(S, exp->data); exp = exp->next;

		 break;
	     
	 case ')':
		 GetTop(S, e);
		 if ((!StackEmpty(S))&&( e == '('))
		 {
			 Pop(S, e); exp = exp->next;
		 }
		  else
			 state = 0;
	 break;

	 case ']':
		 GetTop(S, e);
		 if (!StackEmpty(S) &&  (e == '['))
		 {
			 Pop(S, e); exp = exp->next;
		 }
		 else
			 state = 0;
	 break;

	 case '}':
		 GetTop(S, e);
		 if (!StackEmpty(S) && (e == '{'))
		 {
			 Pop(S, e); exp = exp->next;
		 }
		 else 
			 state = 0;
	 break;

	}

}

if (StackEmpty(S) && state) return true;
else return false;
}

Queue.h
#pragma once
#include
using namespace std;
typedef char ElemType;
typedef struct QNode
{
ElemType data;
struct QNode *next;

}QueuePtr;
typedef struct
{ // 链队列类型
QNode
front; // 队头指针
QNode* rear; // 队尾指针
}Queue;

//Queue Q;

bool InitQueue(Queue &Q);

bool EnQueue(Queue &Q, ElemType e);

bool DeQueue(Queue &Q, ElemType &e);

void DataEn(Queue &Q);

void DataOut(Queue &Q);

void CreateCyclicQueue(Queue &Q, int L);

void en(Queue &Q);

void out(Queue &Q);

Queue.cpp
#include"Queue.h"
#include"conio.h"

bool InitQueue(Queue &Q)
{
// 构造一个空队列Q
Q.front = Q.rear = new QNode;
if (!Q.front) return false; //存储分配失败
Q.front->next = NULL;
return true;
}

bool EnQueue(Queue &Q, ElemType e)
{// 插入元素e为Q的新的队尾元素
QueuePtr p;
p = new QNode;
if (!p) return false; //存储分配失败
p->data = e; p->next = NULL;
Q.rear->next = p; Q.rear = p;
return true;
}

bool DeQueue(Queue &Q, ElemType &e)
{
// 若队列不空,则删除Q的队头元素,
//用 e 返回其值,并返回true;否则返回false
QueuePtr p;
if (Q.front == Q.rear) return false;
p = Q.front->next; e = p->data;
Q.front->next = p->next;
if (Q.rear == p) Q.rear = Q.front;
delete §; return true;
}

void en(Queue &Q)
{

char X=0;

while (1)
{
	

	if (_kbhit());//输入了字符
	{
		X = _getch();
		cout << "输入了" << X << '\n';
		EnQueue(Q, X);
	}

}

}

void out(Queue &Q)
{
char P,l=1;
while (1)
{
if (Q.rear != Q.front)
{
DeQueue(Q, P);
cout << “显示” << P << ‘\n’;
}
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值