2021-3-31 数据结构

学习目标:

线性表

学习内容:

双链表的基本操作(查找,插入,删除);
数据结构线性表大题;

学习时间:

2021.3.31 12:00-1:00

学习产出:

尾插法建立双链表:

void createDlistR(DLNode *& L, int a[], int n)
{
	DLNode* s, * r;
	int i;
	L = (DLNode*)malloc(sizeof(DLNode));
	L->prior = NULL;
	L->next = NULL;
	r = L;
	for (i = 0; i < n; ++i)
	{
		s = (DLNode*)malloc(sizeof(DLNode));
		s->data = a[i];
		r->next = s;
		s->prior = r;
		r = s;
	}
	r->next = NULL;
}

插入结点的代码:

 s->next=p->next;
 s->prior=p;
*p->next=s;
 s->next->prior=p;

删除结点的算法:

 q=p->next;
 p->next=q->next;
 q->next->prior=p;
free(p); 
*/

逆置问题 :
给定一个线性表,如何将其中的元素逆置
思路:可设置两个整型变量i和j,i指向第一个元素, j指向最后一个元素,边交换i和j所指元素,边让i和j相向而行,直到相遇。

//k=n/2   or k=(n-1)/2
for (int i = left, int j = right; i < j; ++i, --j)//两者相向
{
	tempsum = a[i];
	a[i] = a[j];
	a[j] = tempsum;//交换两个元素

}

延伸(1):将一长度为n的数组的前端k(k<n)个元素逆序后移动到数组后端,要求原数组中数据不丢失,其余元素的位置无关紧要。
思路将上述循环的条件发生改变即可。

void reverse(int a[], int left, int right, int k)
{
	int tempsum;
	for (int i = left, int j = right; i < left + k && i < j; ++i, --j)
	{
		tempsum = a[i];
		a[i] = a[j];
		a[j] = tempsum;
	}
}

延伸(2):将一长度为 n的数组的前端k(k<n)个元素保持原序移动到数组后端,要求原数组中数据不丢先,其余元素的位置无关紧要
**思路:**先将前端数据逆置,再逆置两端。

void moveToEnd(int a[], int n, int k)
{
	revetse(a, 0, k - 1, k);
	revetse(a, 0, n - 1, k);
}

延伸(3):将数组中的元素(X[0], X[1], … X[n-1]), 经过移动后变为(X[p], X[p+1], … X[n-1], X[0], X[1]…,X[p-1]),即循环左移p(0<p<n)个位置。
思路:先将两端分别逆置,再逆置两端。

void moveP(int a[], int n, int p)
{
	revetse(a, 0, n - 1, p);
	revetse(a, p, n - 1, n-p);
	revetse(a, 0, n - 1, n);
}

例题1:
设顺序表用数组A[]表示,表中元素存储在数组下标0~m+n-1的范围内,前m个元素递增有序,后n个元素也递增有序,设计一个算法,使得整个顺序 表有序。

(1)给出算法的基本设计思想。

(2)根据设计思想,采用C或C++语言描述算法,并在关键之处给出注释。
**思路:**将m和n看成两个表 ,将一个人表拆分成若干元素填入另外一个表中。

void insertElem(int A[], int m, int n)
{
	int i, j;
	int tempsum;//用于辅助变量的暂存和交换+
	for (i = m; i < m + n; ++i)//将[m,...,m+n-1]插入到[o,...,m-1]
	{
		tempsum = A[];
		for (j = i - 1; j >= 0 && tempsum < A[j]; --j)
		{
			A[j + 1] = A[j]; //元素后移一位
			A[j + 1] = tempsum;
		}
	}
}

例题2:
己知递增有序的单链表A、B (A、B中元素个数分别为m、n,且A、B都带有头结点)分别储存了一个集合,请设计算法,以求出两个集合A和B的差集A-B (仅由在A中出现而不在B中出现的元素所构成的集合)。将差集保存在单链表A中,并保持元素的递增有序性。

(1)给出算法的基本设计思想。

(2)根据设计思想,采用C或C++语言描述算法,并在关键之处给出注释。

(3)说明你所设计的算法的时间复杂度。
思路:在A中删除共有元素即可

void difference(LNode* A, LNode* B)
{
	LNode* p = A->next, * q = B->next;         //设置两指针分别指向A B
	LNode* pre = A;                            //pre为指向p的前驱指针
	LNode* r;
	while(p!=NULL&&q!=NULL)
	{
		if (p->data < q->data)
		{
			pre = p;
			p = p->next;                       //指针依次后移
		}
		else if (p->data > q->data)
		{
			q = q->next;
		}
		else                                   //二者相同,开始删除
		{
			pre->next = p->next;              
			r = p;
			p = p ->next;
			free(r);                           //释放结点空间
		}

	}
}

(3):时间复杂度:O(m+n)。
参考书目
《2022数据结构高分笔记》 ——率辉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值