再回首,数据结构——线性表、链表上的常见算法


       最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会。


       希望这些能提供给初学者一些参考。


//1.编写算法实现线性表就地逆置的操作
void InverseList (SeqList l)
{
	for (i = 0; i <= (l.length-1)/2; i++)
	{
		l.elem[i] <-> l.elem[l.length-1-i];
	}
}
//2.从顺序表中删除自第i个元素开始的k个元素
void DeleteList(SeqList l, int i, int k)
{
	if (i < 0 || i > l.length-1 || k < 0)
	{
			printf ("Error!");
			return;
	}
	if (i+k <= l.length)
	{
		for (j = i+k; j < l.length; j++)
			l.elem[j-k] = l.elem[j];
		l.length -= k;
	}
	else
		l.length = i;
}

//3若已建立一个带头结点的单链表,h为指向头结点的指针
//且链表中存放的数据按从小到大的顺序排列。
//编写函数实现算法,把x的值插入链表中,插入后链表保持有序
void InsertList(LinkList h, ElementType x)
{
	if (NULL == h->next)
	{
		p = (LinkList)malloc(sizeof(LinkNode));
		p->data = x;
		p->next = NULL;
		h->next = p;
	}
	pre = h->next;
	p = h;
	while (pre->next != NULL && pre->data < x)
	{
		p = pre;
		pre = pre->next;
	}
	if (NULL == pre->next && pre->data < x)
	{
		q = (LinkList)malloc(sizeof(LinkNode));
		q->data = x;
		q->next = NULL;
		pre->next = q;
	}
	else //NULL != pre->next && pre->data > x || NULL == pre->next && pre->data >= x
	{
		q = (LinkList)malloc(sizeof(LinkNode));
		q->data = x;
		q->next = pre;
		p->next = q;
	}
}

//4.假设在长度大于1的单循环链表中,既无头结点,也无头指针,
//P为指向该链表中某个节点的指针,
//编写算法,实现删除该节点的前驱节点
void DeleteLinkList(LinkList p)
{
	pre = p->next;
	while (pre->next != p)
		pre = pre->next;
	pp = pre->next;
	pre->next = pre->next->next;
	free(pp);
}

//5.设h为指向单链表头结点的指针,该链表中的值乱序
//设计算法,实现删除链表中值相同的节点,使之只保留一个
void DeleteSelectLinkList(LinkList h)
{
	p = h->next;
	if (!p)
		return;
	x = p->data;
	while (p->next)
		if (x != p->next->data)
		{
			x = p->next->data;
			p = p->next;
		}
		else
		{
			q = p->next;
			p->next = p->next->next;
			free(q);
		}
}

/*6.删除带头结点的单链表h(指向头结点)中值为x的结点的前驱结点*/
void DeleteLinkList(LinkList h, ElementType x)
{
	if (!(h->next))
		return;
	if (!(h->next->next))
		return;
	pre = h->next->next;
	p = h;
	while (pre->next && pre->data != x)
	{
		pre = pre->next;
		p = p->next;
	}
	if (x == pre->data)
	{
		q = p->next;
		p->next = pre;
		free(q);
	}
}

//注意理解
/*7.la,lb分别为表示集合A,B的带头结点的单链表的头指针,A-B(两个集合的差)由la链表返回*/
LinkList Subtraction (LinkList la, LinkList lb)
{
	LinkList pre = la->next;
	while (pre)
	{
		while (lb->next)
		{
			if (pre->data == lb->next->data)
			{
				p = pre;
				pre = pre->next;
				free(p);
			}
			lb = lb->next;
		}
		pre = pre->next;
	}
	return la;
}

/*8_1.集合A,B,C对应的顺序递增表为la,lb,lc,C=A∩B由lc表示*/
SeqList Intersection (SeqList la, SeqList lb)
{
	lc.length = 0;
	for (i = 0; i < la.length; i++)
	{
		for (j = 0; j < lb.length && la.elem[i] != lb.elem[j]; j++)
			;
		if (j < lb.length)
		{
			lc.elem[length++] = la.elem[i];
		}
	}
	return lc;
}

/*8_2.la,lb,lc分别为表示集合A,B,C的带头结点的递增有序的单链表的头指针,
  C=A∩B由lc链表返回*/
//改为有修改后的lc链表返回

LinkList Intersection (LinkList la, LinkList lb)
{
	pre = la->next;
	while (pre)
	{
		while (lb->next && pre->data != lb->data)
			lb = lb->next;
		if (lb->next)
		{
			la->next = pre;
		}
		pre = pre->next;
	}
	return la;
}

/*9删除带头结点的无序表中,元素值大于min且小于max的节点*/
void Delete (LinkList h, ElementType min, ElementType max)
{
	h = h->next;
	while (h)
	{
		if (h->data > min && h->data < max)
		{
			q = h;
			h = h->next;
			free(q);
		}
		h = h->next;
	}
}

/*10.h为带头结点的单链表的头指针,该表中含有两类字符数据元素:字母与数字,
  拆分h为两条带头结点的单项循环链表*ph1、*ph2,其中*ph1链中存放字母,
  *ph2链中存放数字*/
void Separation (LinkList h, LinkList h1, LinkList h2)
{
	if (!(h->next))
		return;
	p = h;
	h = h->next;
	free(p);
	
	h1 = (LinkList)malloc(sizeof(LinkNode));
	
	h2 = (LinkList)malloc(sizeof(LinkNode));
}



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。