算法基础——链表、队列、串、kmp求子串位置

一. 时间复杂度:

用程序中语句总的执行次数间接表示程序的运行时间。
以一段简单的 C 语言程序为例,预估出此段程序的运行时间:

for(int i = 0 ; i < n ; i++) //<- 从 0 到 n,执行 n+1 次
{
a++; //<- 从 0 到 n-1,执行 n 次
}

可以看到,这段程序中仅有 2 行代码,其中:
for 循环从 i 的值为 0 一直逐增至 n(注意,循环退出的时候 i 值为 n),因此 for 循环语句执行了 n+1 次
而循环内部仅有一条语句,a++ 从 i 的值为 0 就开始执行,i 的值每增 1 该语句就执行一次,一直到 i 的值为 n-1,因此,a++ 语句一共执行了 n 次。
因此,整段代码中所有语句共执行了 (n+1)+n 次,即 2n+1 次。数据结构中,每条语句的执行次数,又被称为该语句的频度。整段代码的总执行次数,即整段代码的频度。

2.用大 O 记法的表示方法
格式如下:
O(频度)
其中,这里的频度为最简之后所得的频度。

二. 空间复杂度

和时间复杂度类似,一个算法的空间复杂度,也常用大 O 记法表示。
要知道每一个算法所编写的程序,运行过程中都需要占用大小不等的存储空间,例如:
程序代码本身所占用的存储空间;
程序中如果需要输入输出数据,也会占用一定的存储空间;
程序在运行过程中,可能还需要临时申请更多的存储空间。
对算法的空间复杂度影响最大的,往往是程序运行过程中所申请的临时存储空间。不同的算法所编写出的程序,其运行时申请的临时存储空间通常会有较大不同。
我们先看一个代码:

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
j = i;
j++;
}

这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n);

三.基本数据结构

链表、以及kmp算法的实现

struct student {
	string name;
	int age;
	student* pNext;
};

//链表的实现
void addNode(student* pList, student& newNode) {
	student* p= pList;
	while (p->pNext) {
		p = p->pNext;
	}
	p->pNext = new student(newNode);
}

void traverseList(student* pList) {
	student* p = pList->pNext;
	while (p) {
		//string name = p->name;
		cout << "name:" << p->name << ",age:" << p->age << endl;
		p = p->pNext;
	}
}

void clearList(student* pList) {
	student* p = pList->pNext;
	student* curDelElem = NULL;
	while (p)
	{
		curDelElem = p;
		p = p->pNext;
		cout << "delete " << curDelElem->name << endl;
		delete curDelElem;
		curDelElem = NULL;
	}
}

void mergeTwoList(student* pList1, student* pList2) {
	student* elem1 = pList1->pNext;
	student* elem2 = pList2->pNext;
	student* beforeElem1 = pList1;
	student* beforeElem2 = pList2;
	while (elem1 && elem2) {
		if (elem1->age < elem2->age) {
			beforeElem1 = elem1;
			elem1 = elem1->pNext;
			//string str1 = elem1->name;
			//string str2 = elem2->name;
		}
		else {
			string test1;
			string test2;
			student* addElem = elem2;
			elem2 = elem2->pNext;

			beforeElem1->pNext = addElem;
			addElem->pNext = elem1;
			beforeElem1 = addElem;
			if(elem1)
				test1 = elem1->name;
			if (elem2)
				test2 = elem2->name;
		}
	}
	if (!elem1 && elem2) {
		beforeElem1->pNext = elem2;
		beforeElem1 = elem2;
		elem2 = elem2->pNext;
	}
	delete pList2;
}

void test04() {
	student* pList1 = new student();
	addNode(pList1, student{ "zhang",18 });
	addNode(pList1, student{ "li",19 });
	addNode(pList1, student{ "wang",25 });
	//addNode(pList1, student{ "zhou",30 });
	//addNode(pList1, student{ "chen",35 });
	//traverseList(pList1);

	student* pList2 = new student();
	addNode(pList2, student{ "zhao",19 });
	addNode(pList2, student{ "liu",21 });
	addNode(pList2, student{ "zhu",22 });
	addNode(pList2, student{ "xia",40 });
	addNode(pList2, student{ "sang",45 });
	addNode(pList2, student{ "ge",50 });

	mergeTwoList(pList1, pList2);
	traverseList(pList1);
}

void test05() {
	student* pStart = new student[5];
	student* pEnd = pStart;
	*pEnd++ = student{ "zhang",18 };
	*pEnd++ = student{ "li",19 };
	cout << pStart[0].name << endl;
	cout << pStart[1].name << endl;
	//pEnd = pEnd + 1;
	int dis = pEnd - pStart;
} 

//队列的实现
//循环队列留一个空位
struct queStudent {
	student* base;
	int front;
	int rear;
};


queStudent creatQue() {
	queStudent stuQue1;
	stuQue1.base = new student[5];
	stuQue1.front = 0;
	stuQue1.rear = 0;
	return stuQue1;
}

bool isFull(queStudent& que) {
	if ((que.rear + 1) % 5 == que.front)//循环队列留一个空位
	{
		return true;
	}
	return false;
}

bool isEmpty(queStudent& que) {
	if (que.rear == que.front)
	{
		return true;
	}
	return false;
}

bool pushQue(queStudent& que, student& elem) {
	if (isFull(que))
	{
		return false;
	}
	que.base[que.rear] = elem;
	que.rear = (que.rear+1) % 5;
}

bool popQue(queStudent& que) {
	if (isEmpty(que))
	{
		return false;
	}
	cout << "pop " << que.base[que.front].name << endl;
	que.front = (que.front + 1) % 5;
}

void test06() {
	queStudent stuQue1= creatQue();
	int i = 0;
	string name = "zhang";
	while (!isFull(stuQue1)) {
		string curName = name + to_string(i);
		pushQue(stuQue1, student{ curName,19 });
		i++;
	}
	if (!isEmpty(stuQue1)) popQue(stuQue1);
	pushQue(stuQue1, student{ "li",19 });

	while (!isEmpty(stuQue1))
	{
		popQue(stuQue1);
	}
}
//串///
// "qwaefge"
// "aef"
//暴力求相同字串法
int findEqualString(string& mainStr,string& subString) {
	if (mainStr.size() < subString.size()) return -1;

	int i = 0, j = 0;
	while(i < mainStr.size() &&j<subString.size())
	{
		if (mainStr[i] == subString[j]) {
			++i;
			++j;
		}
		else {
			i = i - j+1;
			j = 0;
		}
	}
	if (j == subString.size()) {
		return i - j;
	}
	return -1;
}

void test07() {
	int pos = findEqualString(string("qwaefgeegeewqw"), string("aefge"));
	cout << pos << endl;
}

//kmp求相同字串法
//求next数组   string s1("qwaefqwageewqw");
void getNext(string str,int next[]) {
	int j = 0, k = -1;
	next[0] = -1;
	cout << "next:" << -1 << "  ";
	while (j < str.size() - 1) {
		/*	if (j == 6)
				int aa = 0;*/

		if (k == -1 || str[j] == str[k]) {
			j=j+1;
			k=k+1;
			next[j] = k;
			cout << k << "  ";
		}
		else{
			k = next[k];
		}

	}
	cout << endl; 
}

int getSubStrPos(string& s1,string& subStr) {
	int next[100] = { -2 };
	memset(next, 10, sizeof(next));
	getNext(s1, next);

	int i = 0;
	int j = 0;
	while (i < s1.size()&& j<subStr.size()){
		if (j == -1 || s1[i] == subStr[j]){
			i++;
			j++;
		}
		else {
			j = next[j];
		}
	}
	if (j == subStr.size())
		return i - j;
	return -1;
}

void test08() {
	string s1("qwaefqwageewqw");
	string s2("fqw");
	int pos = getSubStrPos(s1,s2);

	int aa = 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值