C语言版数据结构- C语言实现串,含详细的源代码

  • HString.h 头文件
#include <stdio.h>
#include <stdlib.h>
//定义函数返回的类型
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//定义数据元素的类型为字符型
typedef int Status;
typedef char ElemType; 
//定义单链表的存储结构
typedef struct {
	char* ch;
	int length;
}HString;


Status StrAssign(HString &T, char* chars) {
//	if(T.ch != NULL) {
//		free(T.ch);
//	}
	int i;
	char* c;
	for(i=0,c=chars; *c; i++, c++);
	if(!i) {
		T.ch = NULL;
		T.length = 0;
	} else {
		if(!(T.ch=(char*)malloc(i*sizeof(char)))) {
			exit(OVERFLOW);
		}
		for(int j=0; j<i; j++) {
			T.ch[j] = chars[j];
		}
		T.length = i;
	}
	return OK;
}


int StrLength(HString S) {
	return S.length;
}


Status SubString(HString &Sub, HString S, int pos, int len) {
	if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1) {
		return ERROR;
	}
//	if(Sub.ch != NULL) {
//		free(Sub.ch);
//	}
	if (!len) {
		Sub.ch = NULL;
		Sub.length = 0;
	} else {
		Sub.ch = (char*)malloc(len*sizeof(char));
		for (int j = 0,i = pos-1; j<len; j++, i++) {
			Sub.ch[j] = S.ch[i];
			Sub.length = len;
		}
		
	} 
	return OK;
}

Status Concat(HString &T, HString S1, HString S2) {

	
	if(!(T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char)))) {
		exit(OVERFLOW);
	}
	
	for(int i = 0; i<S1.length; i++) {
		T.ch[i] = S1.ch[i];
	}
	
	T.length = S1.length + S2.length;
	for(int i = S1.length, j = 0; i<T.length; i++, j++) {
			T.ch[i] = S2.ch[j];
	}
	return OK;
	
	
}




Status StrDelete(HString S, HString &s2, int pos, int len) {
	HString temp;
	if(!(temp.ch = (char*)malloc((S.length-len)*sizeof(char)))) {
		exit(OVERFLOW);
	}
	temp.length = S.length-len;
	int i;
	for(i=0; i<pos-1; i++) {
		temp.ch[i] = S.ch[i];
	}
	for(int j=i+len; j<S.length; j++,i++) {
		temp.ch[i] = S.ch[j];
	}
	
	s2 = temp;
	return OK;
}


int Index_KMP(HString S, HString T, int pos,int next[]) {
	//利用模式串T的next函数求T在主串中第pos个字符之后的位置的KMP算法。
	int i = pos;
	int j = 0;
	while (i<S.length&&j<T.length)
	{
		if (j == -1 || S.ch[i] == T.ch[j]) { ++i; ++j; }
		else
		{
			j = next[j];
		}
	}
	if (j >= T.length)return i - T.length+1;	//匹配成功
	else return 0;								//输出-1失败
}


exp-1 主程序:测试基本功能

#include "HString.h"


int main() {
	
	HString s;
	HString s1;
	printf("%s\n", "(1)建立串");
	char str1[] = "abcdefghxyzhijklmn";
	char str2[] = "xyz";
	StrAssign(s, str1);
	StrAssign(s1, str2);

	printf("%s%s\n", "(2)输出串s:", s.ch);
	printf("%s%d\n", "(3)输出串s的长度:", StrLength(s));
	//将串s分为两个子串
	HString s_sub1;
	HString s_sub2;
	SubString(s_sub1, s, 1, 8);
	SubString(s_sub2, s, 9, StrLength(s)-8);
	printf("%s\n", "(4)在串s的第9个字符位置插入串s1而产生s2");

	//将s1先与前部分的子串连接,得到temp,再将temp和后部分子串连接,从而实现插入操作
	HString s2;
	HString temp;
	Concat(temp, s_sub1, s1);
	Concat(s2, temp, s_sub2);
	printf("%s%s\n", "(5)输出串s2:", s2.ch);
	
	printf("%s\n", "(6)删除s的第2个字符开始的5个字符而产生串s2");
	StrDelete(s, s2, 2, 5);
	printf("%s%s\n", "(7)输出串s2:", s2.ch);
	
	printf("%s\n", "(8)删除s的第2个字符开始的5个字符替换成s1而产生串s2");
	HString s2_sub1;
	HString s2_sub2;
	SubString(s2_sub1, s2, 1, 1);
	SubString(s2_sub2, s2, 2, s2.length-1);
	Concat(temp, s2_sub1, s1);
	Concat(s2, temp, s2_sub2);
	printf("%s%s\n", "(9)输出串s2:", s2.ch);
	printf("%s\n", "(10)提取串s的第2个字符开始的10个字符而产生s3");
	HString s3;
	SubString(s3, s, 2, 10);
	printf("%s%s\n", "(11)输出串s3:", s3.ch);
	printf("%s\n", "(12)将串s1和s2连接起来而产生串s4");
	HString s4;
	Concat(s4, s1, s2);
	printf("%s%s\n", "(13)输出串s4:", s4.ch);
	int next[10] = { -1,0,0,1,1,2,0,1 };
	int leng = Index_KMP(s, s1, 1, next);
	printf("%s%d\n", "(14)输出串s1在主串s中的位置,如不存在输出0, 首元素的位置为:",leng);
	return 0;
	
}

  • 测试结果
    在这里插入图片描述
  • exp-2 主程序:利用该结构进行字符加密解密
#include "HString.h"
HString A;
HString B;
char a[] = "abcdefghijklmnopqrstuvwxyz";
char b[] = "ngzqtcobmuhelkpdawxfyivrsj";


HString EnCrypt(HString p) {
	HString enCrypt_p;
	enCrypt_p.ch = (char*)malloc(p.length*sizeof(char));
	enCrypt_p.length = p.length;
	
	for (int i=0; i<p.length; i++) {
		for (int j=0;  j<A.length; j++) {
			if (p.ch[i] == A.ch[j]) {
				enCrypt_p.ch[i] = B.ch[j];
			}
		}
	}
	return enCrypt_p;
	
}

HString UnEncrypt(HString q) {
	
	HString unCrypt_q;
	unCrypt_q.ch = (char*)malloc(q.length*sizeof(char));
	unCrypt_q.length = q.length;
	
	for (int i=0; i<q.length; i++) {
		for (int j=0;  j<B.length; j++) {
			if (q.ch[i] == B.ch[j]) {
				unCrypt_q.ch[i] = A.ch[j];
			}
		}
	}
	
	
	return unCrypt_q;
}
int main() {

	HString p;
	StrAssign(A, a);
	StrAssign(B, b);
	
	char aa[] = "encrypt";
	StrAssign(p, aa);
	HString enCrypt_p = EnCrypt(p);
	printf("%s%s\n", "p串被加密后: ", enCrypt_p.ch);
	
	HString unCrypt_p = UnEncrypt(enCrypt_p);
	printf("%s%s\n", "q串被解密后: ", unCrypt_p.ch);
	return 0;
	
}


  • 测试结果
    在这里插入图片描述
数据结构》(C语言) 算法源码及运行演示系统使用说明 一、启动演示系统 双击演示系统应用程序文件“DS_VC_ALGO.EXE”启动演示系统,出现图1所示界面。 图1 《数据结构》(C语言)算法源码及运行演示系统主界面 二、演示系统使用步骤 除了个别算法之外,演示系统给出了《数据结构》(C语言)书中算法对应的程序代码(CPP文件)和测试运行程序(VC++6.0的EXE文件)。通过本系统,可以显示算法的源代码以及运行结果。具体操作步骤如下: 1.选择相应章 单击演示系统界面右侧章选择按钮。 例如,要选择第6章,则单击“第6章”选择按钮。 当相应章被选择后,窗口的右侧部分将列出本章的算法选择按钮。 例如,选择第6章后,窗口的右侧部分将显示第6章中的算法6.1-6.13和6.15的选择按钮。由于书中的算法6.14和6.16只是示意性算法,故未给出源码,其按钮上的文字为灰色,处于“无效”状态。 2.选择相应章中的算法 单击窗口右侧部分所列举的本章某个算法选择按钮,被选择的算法的源码将在窗口左侧空白区域中显示。对于较长的源码,单击显示区域后,可用键盘的光标键和翻页键浏览源码。 例如,选择了第6章中的算法6.5后界面如图2所示: 图2 选择算法6.5 3.运行测试程序 单击窗口上部的“运行”按钮,将弹出运行窗口,运行所选算法的测试程序。若运行按钮为灰色,表示该算法无单独测试程序。 例如,算法6.5的测试运行窗口如图3所示: 图3 测试运行窗口 测试运行说明: 测试运行窗口显示程序的执行过程及结果。若在显示过程中出现运行窗口无法正常演示的情况,只需调节运行窗口大小即可正常显示(调节最小化按钮或窗口最大化/还原按钮“ ”)。 三、退出演示系统 使用完毕后,单击窗口右上角关闭按钮“ ”退出演示系统。 四、测试程序示例 在《数据结构》的课程教学中,各抽象数据类型的设计与实现是重要的学习和实践环节。为此,本系统只给出了各算法源码的测试程序的可执行文件。在此,给出算法6.5的测试程序示例,以供参考。 算法6.5是中序遍历线索二叉树的非递归算法,要对其源码进行测试,可首先调用算法6.6及6.7建立中序线索二叉树。以下是测试程序的源码,相关类型和辅助函数定义在文件include06.h和include06.cpp中,此略。 // test0605.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "include06.h" // 相关类型和辅助函数的定义 BiThrTree pre; // 线索二叉树遍历辅助变量 #include "algo0607.cpp" // 算法6.7源码 #include "algo0606.cpp" // 算法6.6源码 #include "algo0605.cpp" // 算法6.5源码 int main(int argc, char* argv[]) { char gl_str[64]; BiThrTree T; BiThrTree Thrt; printf("*******************************************\n"); printf("* 《数据结构》(C语言)严蔚敏,吴伟民 *\n"); printf("* 算法6.5, 6.6 & 6.7 *\n"); printf("*******************************************\n"); srand((unsigned)time(NULL)); // 随机函数初始化 T=NULL; // 空二叉树T for (int pass=0; pass<5; pass++) { // 测试运行5次,第一次为空树 outBiThrTree(T,gl_str); // 以类广义表的形式输出二叉树T到gl_str printf("T = %s\n", gl_str); // 显示 pre = NULL; Status r = InOrderThreading(Thrt, T); // 算法6.6,6.7,中序线索化 printf("InOrderThreading(Thrt, T) : %s\n", (r) ? "OK" : "ERROR"); initVisitStr(); // 将visitStr清为空 InOrderTraverse_Thr(Thrt, v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值