链式表示的线性表之二——循环单链表2——拆分循环单链表(字符型)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36669549/article/details/84231659

已知L为指向单链表头结点的指针,每个节点数据域存放一个字符,该字符可能是英文字母字符,数字字符或者其他字符。编写算法,构造三个带头结点的循环单链表,使得每个表中只含有同一类字符。
 

这是东北大学考研题目的变形,为了便于程序的编写,这里为L增加一个头结点(原题上不带头结点)。这个题目考察单链表的基本操作(单链表和循环链表操作基本相同)。首先为3个循环单链表建立头结点并初始化,若将一个单链表分解成3个,可以按照每个字符的ASCII进行分类,遇到‘A’--'Z'和‘a’--'z'的字符,将其插入ha中;遇到‘0’--‘9’这样的字符,将其插入hb中;剩下的插入hc中。

LinkList.h

#pragma once
#include <iostream>
typedef char DataType;
using namespace std;
 
/*02_01??存储结构*/
typedef struct Node
{
	DataType data;
	struct Node *next;
}ListNode, *LinkList;/*ListNode是链表的结点类型,LinkList是指向链表结点的指针类型*/
/*02??基本运算*/
/*02_01??初始化单链表*/
void InitList(LinkList *head)
{
	if ((*head=(LinkList)malloc(sizeof(ListNode)))==NULL)
	{
		/*02_01为头结点分配一个存储单元*/
		exit(-1);
	}
	(*head)->next = NULL;/*02_01将单链表的头结点指针域置为空 */
 
}
/*02_02判断单链表是否为空*/
int ListEmpty(LinkList head)
{
	if (head->next==NULL)/*02_02如果单链表头结点的指针域为空*/
	{
		return 1;        /*02_02返回1*/
	}
	else
	{
		
		return 0;        /*02_02返回1*/
	}
}
 
/*02_03按照序号查找*/
ListNode *Get(LinkList head, int i)
/*02_03按照序号查找单链表中第i个结点,查找成功返回该结点的指针表示成功;否则返回NULL表示失败*/
{
	ListNode *p;
	int j;
	if (ListEmpty(head))
	{
		return NULL;
	}
	if (i<1)
	{
		return NULL;
	}
	j = 0;
	p = head;
	while (p->next!=NULL&&j<i)
	{
		p = p->next;
		j++;
 
	}
	if (j==i)
	{
		return p;
 
	}
	else
	{
		return NULL;
	}
 
}
 
/*02_04查找元素值为e的结点的元素,若查找成功则返回对应元素的结点指针,否则返回NULL表示失败*/
ListNode *LocateElem(LinkList head, DataType e)
{
	ListNode *p;
	p = head->next;
	while (p)
	{
		if (p->data!=e)
		{
			p = p->next;
		}
		else
		{
			break;
		}
	}
	return p;
}
 
/*02_05定位操作,确定元素所在单链表中的序号*/
/*02_05从头指针出发依次访问每个结点,并将结点的值与e比较,如果相等,则返回该结点序号表示成功*/
/*02_05如果没有与e相等的元素则返回0表示失败*/
 
int LocatePos(LinkList head, DataType e)
{
	ListNode *p;
	int i;
	if (ListEmpty(head))/*02_05在查找第i个元素之前,判断链表是否为空*/
	{
		return 0;
	}
	p = head->next;    /*02_05指针指向第一个结点*/
	i = 1;
	while (p)
	{
		if (p->data==e) /*02_05找到与e相等的元素*/
		{
			return i;   /*02_05返回该序号*/
		} 
		else
		{
			p = p->next;
			i++;
		}
	}
	if (!p)       /*02_05如果没有找到与e相等的元素*/
	{
		return 0; /*返回0*/
	}
}
 
/*02_06在第i个位置插入元素e*/
 
int InsertList(LinkList head, int i, DataType e)
/*02_06在单链表中的第i个位置插入一个结点,结点的元素值为e。插入成功返回1,失败返回0.*/
{
	ListNode *pre, *p;/*02_06定义第i个元素的前驱结点指向pre,指针p指向新生成的结点*/
	int j;
	pre = head;/*02_06指针p指向头结点*/
	j = 0;
	while (pre->next != NULL&&j < i - 1)
		/*02_06找到第i-1个结点,即第i个结点的前驱结点*/
	{
		pre = pre->next;
		j++;
	}
	if (j!=i-1)/*02_06如果没有找到说明插入位置错误*/
	{
		cout << "02_06插入位置错误!" << endl;
		return 0;
	}
	/*02_06新生成一个结点,并将e赋值给该结点的数据域*/
	if ((p=(ListNode*)malloc(sizeof(ListNode)))==NULL)
	{
		exit(-1);
	}
	p->data = e;
	/*02_06插入结点操作*/
	p->next = pre->next;
	pre->next = p;
	return 1;
 
}
/*02_07删除第i个结点*/
 
int DeleteList(LinkList head, int i, DataType *e)
/*02_07删除单链表中的第i个结点;删除成功返回1,失败返回0。*/
{
	ListNode *pre, *p;
	int j;
	pre = head;
	j = 0;
	while (pre->next!=NULL&&pre->next->next!=NULL&&j<i-1)
	/*02_07判断是否找到前驱结点*/
	{
		pre = pre->next;
		j++;
 
	}
	if (j!=i-1)/*02_07如果没有找到要删除的节点位置,说明删除有误*/
	{
		cout << "02_07删除位置有误" << endl;
		return 0;
	}
	/*02_07指针p指向单链表中的第i个结点,并将该结点的数据域赋值给e*/
	p = pre->next;
	*e = p->data;
	/*02_07将前驱结点的指针域指向要删除结点的下一个结点,也就是将p指向的结点与单链表断开*/
	pre->next = p->next;
	free(p); /*02_07释放p指向的结点*/
	return 1;
 
}
/*02_08求表长的操作*/
int ListLength(LinkList head)
{
	ListNode *p;
	int count = 0;
	p = head;
	while (p->next!=NULL)
	{
		p = p->next;
		count++;
 
	}
	return count;
}
 
/*02_09销毁链表操作*/
 
void DestoryList(LinkList head)
{
	ListNode *p, *q;
	p = head;
	while (p!=NULL)
	{
		q = p;
		p = p->next;
		free(q);
	}
}

 main.cpp

#include <iostream>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <iomanip>
#include "LinkList.h"
typedef char DataType;
LinkList CreateList(DataType a[], int n);
void Decompose(LinkList L,LinkList *ha,LinkList *hb,LinkList *hc);
void DispList(LinkList L);
void DispCycList(LinkList head);
int CycListLength(LinkList head);
void main()
{
	LinkList h, ha, hb, hc;
	int n;
	DataType a[] = { 'a','X','0','$','@','%','p','m','3','9', 'y','*','i','&' };
	n = sizeof(a) / sizeof(a[0]);
	h = CreateList(a, n);
	Decompose(h, &ha, &hb, &hc);
	cout << "大小写英文字母的字符有" << CycListLength(ha) << "个,分别是:" << endl;
	DispCycList(ha);
	cout << "数字字符的有" << CycListLength(hb) << "个,分别是:" << endl;
	DispCycList(hb);
	cout << "其他字符有" << CycListLength(hc) << "个,分别是:" << endl;
	DispCycList(hc);


	system("pause");
}

LinkList CreateList(DataType a[], int n)
{
	LinkList L;
	int i;
	InitList(&L);
	for (i = 1; i <= n;i++)
	{
		if (InsertList(L,i,a[i-1])==0)
		{
			cout << "插入位置不合法!" << endl;
			return NULL;
		}
	}
	DispList(L);
	return L;
}
void Decompose(LinkList L, LinkList *ha, LinkList *hb, LinkList *hc)
{
	ListNode *p, *q;
	p = L->next;
	*ha = (LinkList)malloc(sizeof(ListNode));
	*hb = (LinkList)malloc(sizeof(ListNode));
	*hc = (LinkList)malloc(sizeof(ListNode));

	(*ha)->next = (*ha);
	(*hb)->next = (*hb);
	(*hc)->next = (*hc);

	while (p)
	{
		if ((p->data>='A'&&p->data<='Z')|| (p->data >= 'a'&&p->data <= 'z'))
		{
			q = p;
			p = p->next;
			q->next = (*ha)->next;
			(*ha)->next = q;
		}
		else if (p->data>='0'&&p->data<='9')
		{
			q = p;
			p = p->next;
			q->next = (*hb)->next;
			(*hb)->next = q;
		}
		else
		{
			q = p;
			p = p->next;
			q->next = (*hc)->next;
			(*hc)->next = q;
		}

	}
}

void DispList(LinkList L)
{
	int i;
	LinkList p;
	cout << "单链表L中的元素有" << ListLength(L) << "个" << endl;

	for (i = 1; i <= ListLength(L);i++)
	{
		p = Get(L, i);
		if (p)
		{
			cout << setw(4) << p->data;
		}
	}
	cout << endl;
}

void DispCycList(LinkList h)
{
	ListNode *p = h->next;
	if (p==NULL)
	{
		cout << "链表为空!" << endl;
		return;
	}
	while (p->next!=h)
	{
		cout << setw(4) << p->data;
		p = p->next;
	}

	cout << setw(4) << p->data;
	cout << endl;
}

int CycListLength(LinkList head)
{
	ListNode *p;
	int count = 0;
	p = head;
	while (p->next!=head)
	{
		p = p->next;
		count++;
	}
	return count;
}

结果:

猜你喜欢

转载自blog.csdn.net/baidu_36669549/article/details/84231659