递归--实现线性表搜索指定关键字值的元素

 这里采用链表的形式储存数值

链表结束的标志为sl->next==NULL,所以当链表到达最后一个节点时,需要考虑最后一个结点的data是否为查找数值。

这里通过设置一个全局变量i,通过i每一次递归的增加来记录结点位置。

不符合查找数值则通过sl=sl->next移动至下一个节点判断,直至找到查找元素或者单链表遍历结束

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
typedef int DataType;

//不带头单向非循环链表
typedef struct SListNode//单链表结点结构类型
{
	DataType data;//结点数据域
	struct SListNode* next;
	//结点指针域,指针指向下一个结点,而下一个结点的类型也为SListNode
}SLTNode;

//接口函数
void SListPrint(SLTNode* plist);//显示
void SListPushBack(SLTNode** pplist, DataType x);//尾插
void SListPushFront(SLTNode** pplist, DataType x);//头插
void SListPopBack(SLTNode** pplist);//尾删
void SListPopFront(SLTNode** pplist);//头删
//insert与erase的使用以find为前提,通过find找到插入位置即pos
SLTNode* SListFind(SLTNode* plist, DataType x);//查找
void SListInsert(SLTNode** pplist, SLTNode* pos, DataType x);//在pos位置前插入x
void SListErase(SLTNode** pplist, SLTNode* pos);//删除pos位置的值


void SListPrint(SLTNode* plist)
{
	SLTNode* cur = plist;
	while (cur != NULL)//链表的最后一个指针域为NULL
	{
		printf("%d ", cur->data);//输出结点数据域
		cur = cur->next;//通过指针域走向下一个元素
	}
	printf("\n");
}

void SListPushBack(SLTNode** pplist, DataType x)//这里的pplist是plist的地址
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//开辟一块大小与SLTNode相同的空间
	newnode->data = x;//新结点数据域赋值
	newnode->next = NULL;//将新结点的指针域置空
	if (*pplist == NULL)//*pplist其实就是plist
	{
		*pplist = newnode;
		//如果传入形参为SLTNode*型,实参与形参类型相同,形参的改变不影响实参,形参是实参的一个拷贝
		//所以采用指针的方式传递,传入首结点地址,所以采用二级指针SLTNode**
	}
	else
	{
		SLTNode* tail = *pplist;//尾结点的指针需要从链表的第一个元素开始查找
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;//尾结点链接新结点
	}
}

void SListPushFront(SLTNode** pplist, DataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	newnode->data = x;
	newnode->next = NULL;

	newnode->next = *pplist;//插入结点指针域为原来首地址
	*pplist = newnode;
}

void SListPopFront(SLTNode** pplist)
{
	SLTNode* next = (*pplist)->next;//*与->为同一个优先级,所以加()
	free(*pplist);//释放链表首个结点
	*pplist = next;
}

void SListPopBack(SLTNode** pplist)
{
	//assert(pplist != NULL);
	if (*pplist == NULL)//当链表为空
	{
		return;
	}
	else if ((*pplist)->next == NULL)//当仅有一个结点
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		SLTNode* tail = *pplist;
		SLTNode* prev = NULL;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}//prev为tail的前一个指针,当tail到链表的末尾时,prev指向倒数第二个结点
		free(tail);
		prev->next = NULL;
	}
}

SLTNode* SListFind(SLTNode* plist, DataType x)
{
	SLTNode* cur = plist;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void SListInsert(SLTNode** pplist, SLTNode* pos, DataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	newnode->data = x;
	if (pos == *pplist)
	{
		SListPushFront(pplist, x);
	}
	else
	{
		SLTNode* prev = *pplist;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}


void SListErase(SLTNode** pplist, SLTNode* pos, DataType x)
{

	SLTNode* prev = *pplist;
	if (pos == *pplist)
	{
		SListPopFront(pplist);
	}
	else
	{
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

int i = 1;
DataType found(SLTNode* sl,int x)
{
	if (sl->next!=NULL)
	{	
		if (sl->data == x)
		{
			return i;
		}
		else
		{
			sl = sl->next;
			i++;
			found(sl, x);
		}
    }
	else
	{
		if (sl->data == x)
		{
			return i;
		}
		else
		{
			printf("未查找到\n");
			exit(-1);
		}
	}

}



int main()
{
	SLTNode* s1 = NULL;
	SListPushBack(&s1,15);
	SListPushBack(&s1, 121);
	SListPushBack(&s1, 666);
	SListPushBack(&s1, 888);
	SListPushBack(&s1, 857);
	SListPushBack(&s1, 4321);
	SListPrint(s1);

	int x;
	printf("输入查找元素x数值\n");
	scanf_s("%d", &x);
	printf("查找到元素%d位于:%d\n", x,found(s1,x));
	system("pause");
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值