The Road to Algorithms (C++)

1. Linked list

1. The problem of merging two singly linked lists and taking the same data

Question: Suppose A and B are two singly linked lists (lead nodes), in which the elements are in ascending order. Design an algorithm to generate a singly linked list C from the common elements in A and B. It is required that the nodes A and B are not destroyed. Analysis: The requirement
is
not Destroy nodes A and B, so we need to re-create the allocated node space to connect. In order to find common elements, each time an element in A is traversed, it is compared with the elements in B one by one, and the value is given to another space node and connected to C. The time complexity is O(n^2).
Because the two linked lists are in increasing order, we can set up two pointers to be compared synchronously. If they are the same, add c, and the one with the smaller difference will be moved backward until the end of the linked list is reached. The time complexity is 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. The problem of merging two singly linked lists into one singly linked list

Purpose: Master the application of singly linked lists and algorithm design
questions: L1 = (x1, x2, …, xn), L2 = (y1, y2, …, ym), they are two linear lists, using a singly linked list with the leading node To store, design an algorithm to merge L1 and L2, and put the result in the linear table L3.
Requirements:
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 still uses single linked list storage, and the space complexity of the algorithm is O(1).
Idea: Since the space complexity is O(1), L3 can be created on the basis of L1 and L2, that is, L1 and L2 are directly interleaved and linked behind L3.

Algorithm implementation

#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;
}

Guess you like

Origin blog.csdn.net/MOON_YZM/article/details/132025564