Der Weg zu Algorithmen (C++)

1. Verknüpfte Liste

1. Das Problem, zwei einfach verknüpfte Listen zusammenzuführen und dieselben Daten zu verwenden

Frage: Angenommen, A und B sind zwei einfach verknüpfte Listen (Hauptknoten), in denen die Elemente in aufsteigender Reihenfolge sind. Entwerfen Sie einen Algorithmus, um aus den gemeinsamen Elementen in A und B eine einfach verknüpfte Liste C zu generieren. Es ist erforderlich, dass die Knoten A und B werden nicht zerstört. Analyse: Die Anforderung
besteht
nicht darin, die Knoten A und B zu zerstören, daher müssen wir den zugewiesenen Knotenplatz für die Verbindung neu erstellen. Um gemeinsame Elemente zu finden, wird jedes Mal, wenn ein Element in A durchlaufen wird, es nacheinander mit den Elementen in B verglichen und der Wert an einen anderen Raumknoten übergeben und mit C verbunden. Die Zeitkomplexität beträgt O(n^2).
Da die beiden verknüpften Listen in aufsteigender Reihenfolge vorliegen, können wir zwei Zeiger für den synchronen Vergleich einrichten. Wenn sie gleich sind, fügen Sie c hinzu, und der Zeiger mit der kleineren Differenz wird rückwärts verschoben, bis das Ende der verknüpften Liste erreicht ist . Die Zeitkomplexität beträgt O(n).

Code:

#include <stdlib.h>
#include <stdio.h>
//单向链表,如果是双向链表,需要加个head
struct Link {
    
    
	int data;
	struct Link *next;
};
//方法一:不要用这种,简单初级,不考虑时间复杂度
void linkCommon(Link *a, Link *b, Link *c ) {
    
    
	struct Link *lc = c,*la=a->next,*lb=b->next,*rc=lc;
	while (la) {
    
    
		while (lb) {
    
    
			if (la->data==lb->data) {
    
    //如果是公共元素
				struct Link *p = (struct Link*)malloc(sizeof(struct Link));
				p->data = la->data;
				rc->next = p;//采用尾插法
				rc = p;
				break;
			}
			lb = lb->next;
		}
		la = la->next;
		lb = b->next;
	}
	rc->next = NULL;//最后一个节点指针需要指向NULL。
}
//方法二
//a,b是两个已知链表,c是载体,存放相同数据的链表
void listCommon(Link *a,Link *b,Link *c) {
    
    
	struct Link *rc = c, *la = a->next, *lb = b->next;
	while (la&&lb) {
    
    
		if (la->data==lb->data) {
    
    
			struct Link *p = (struct Link*)malloc(sizeof(struct Link));
			p->data = la->data;
			p->next = NULL;
			rc->next = p;
			rc = p;
			la = la->next;
			lb = lb->next;
		}
		else {
    
    
			la->data < lb->data ? la = la->next : lb = lb->next;
		}
	}
	rc->next = NULL;
}
int main() {
    
    
	struct Link *a, *b;
	Link *createLink();
	void printfNowLink(Link *);
	a = createLink();
	b = createLink();
	struct Link *c = (struct Link*)malloc(sizeof(struct Link));
	c->next = NULL;
	//linkCommon(a,b,c);
	listCommon(a,b,c);
	printfNowLink(c);
	return 0;
}

2. Das Problem der Zusammenführung zweier einfach verknüpfter Listen zu einer einfach verknüpften Liste

Zweck: Beherrschen Sie die Anwendung einfach verknüpfter Listen und
Fragen zum Algorithmusdesign: L1 = (x1, x2, …, xn), L2 = (y1, y2, …, ym), es handelt sich um zwei lineare Listen, wobei eine einfach verknüpfte Liste mit verwendet wird Der führende Knoten Entwerfen Sie zum Speichern einen Algorithmus zum Zusammenführen von L1 und L2 und geben Sie das Ergebnis in die lineare Tabelle L3 ein.
Anforderungen:
L3 = (x1, y1, x2, y2, …, xm, ym, x(m+1), xn) m<=n L3 = (x1, y1, x2, y2, …, xn, yn,
y (n+1), ym) m>n
L3 verwendet immer noch den Speicher einer einzelnen verknüpften Liste, und die räumliche Komplexität des Algorithmus beträgt O(1).
Idee: Da die Raumkomplexität O (1) ist, kann L3 auf der Grundlage von L1 und L2 erstellt werden, dh L1 und L2 werden direkt hinter L3 verschachtelt und verknüpft.

Algorithmusimplementierung

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

typedef int ElemType;
typedef struct LNode
{
    
    
	ElemType data;
	struct LNode* next;
}LinkNode;

bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3);		//L1、L2、L3为三个单链表的头结点
bool InitList(LinkNode*& L);		//链表产生
bool DispList(LinkNode* L);			//链表输出

int main(int argc, const char* argv[])
{
    
    
	LinkNode* L1 = NULL, * L2 = NULL, * L3 = NULL;
	int x;
	bool flag = false;
	InitList(L1);
	InitList(L2);
	flag = DivideList(L1, L2, L3);
	if (flag)
		printf("算法执行成功。\n");
	else
		printf("算法执行失败。\n");
	DispList(L3);
	return 0;
}

bool InitList(LinkNode*& L)		//建立单链表
{
    
    
	while (!L) {
    
    
		L = (LinkNode*)malloc(sizeof(LNode));
	}
	L->next = NULL;
	int i, n;
	LinkNode* p = NULL, * q = NULL;
	q = L;
	printf("请输入数据规模:\n");
	scanf("%d", &n);
	printf("请输入数据:\n");
	for (i = 0; i < n; i++) {
    
    
		while (!p) {
    
    
			p = (LinkNode*)malloc(sizeof(LNode));
		}
		scanf("%d", &p->data);
		q->next = p;
		q = p;
		p = q->next = NULL;
	}
	return true;
}
bool DispList(LinkNode* L)		//输出单链表
{
    
    
	LinkNode* p = L->next;
	while (p) {
    
    
		printf("\t%d", p->data);
		p = p->next;
	}
	printf("\n");
	return true;
}
bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3)		//L1、L2、L3为三个单链表的头结点
{
    
    
	//直到L3申请成功
	while (!L3) {
    
    
		L3 = (LinkNode*)malloc(sizeof(LNode));
	}
	LinkNode* p, * q, * r;
	p = L1->next;		//p为L1的工作指针
	q = L2->next;		//q为L2的工作指针
	r = L3;				//r为L3的尾指针
	//当p和q均不为空时
	while (p && q) {
    
    
		r->next = p;	//先接L1
		r = r->next;	//尾指针后移
		p = p->next;	//p指针后移
		r->next = q;	//再接L2
		r = r->next;	//尾指针后移
		q = q->next;	//q指针后移
		r->next = NULL;	//尾指针的next应该置空
	}
	//当p不为空时
	if (p) {
    
    
		r->next = p;	//将剩余的接在尾指针后面
	}
	//当q不为空时
	if (q) {
    
    
		r->next = q;	//将剩余的接在尾指针后面
	}
	return true;
}

Acho que você gosta

Origin blog.csdn.net/MOON_YZM/article/details/132025564
Recomendado
Clasificación