数据结构与算法(3)链表的初始化,按位查找,按值查找,按位序插入,指定结点的前,后插操作,按位序,结点删除,求链表表长,用尾插法建立单链表,打印链表元素——C语言实现

 注意:L可以表示为头指针或是头结点,L->next可以表示为头结点的下一个结点

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>

typedef int ElemType;

//定义一个链表
typedef struct LNode
{
	ElemType data;//结点的数据域
	struct LNode* next;//结点的指针域
}LNode, * LinkList;


bool InitList(LinkList L);//初始化链表
LNode* GetElem(LinkList L, int i);//按位查找
LNode* LocateElem(LinkList L, ElemType e);//按值查找
bool ListInsert(LinkList L, int i, ElemType e);//按位序插入
bool InsertNextNode(LNode* p, ElemType e);//指定结点的后插操作
bool InsertPriorNode(LNode* p, ElemType e);//指定结点的前插操作
bool ListDelete(LinkList L, int i, ElemType e);//按位序删除
bool DeleteNode(LNode* p);//删除指定结点
int length(LinkList L);//求链表表长
LinkList List_Taillnsert(LinkList L);//用尾插法建立单链表
bool PrintList(LinkList L);//打印链表的元素




bool InitList(LinkList L)//初始化链表
{
	printf("********初始化单链表********\n");
	L = (LinkList)malloc(sizeof(LNode));//生成新结点作为头结点,用头指针L指向头结点
	L->next = NULL;//头结点的指针域置空
	if (L->next == NULL)
	{
		printf("链表初始化成功!\n");
	}
	else printf("链表初始化失败!\n");
	return true;
	//system("pause");//暂停,不然控制台程序会一闪即过,你来不及看到执行结果
	//system("cls");
}

LNode* GetElem(LinkList L, int i)//按位查找
{
	if (i < 0)
	{
		printf("输入的位置不合法\n");
	}
	LNode* p;
	int j = 0;
	p = L;
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}

LNode* LocateElem(LinkList L, ElemType e)//按值查找
{
	LNode* p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}

 
bool ListInsert(LinkList L, int i, ElemType e)//按位序插入
{
	if (i < 1)
	{
		printf("输入的位置不合法\n");
	}
		//LNode* p;//当前指针指向的结点
		//int j = 0;//当前指针指向的是第几个结点,0表示指向头结点
		//p = L;
		//while(p != NULL && j < i - 1)//循环找到第i-1个结点
		//{
		//	p = p->next;
		//	j++;
		//}
	LNode* p = GetElem(L, i - 1);             //封装
		/*if(p==NULL)
			printf("输入的位置不合法\n");
		LNode* s = (LNode*)malloc(sizeof(LNode));
		s->data = e;
		s->next = p->next;
		p->next = s;
		printf("插入成功\n");*/
	return InsertNextNode(p, e);              //这里就发挥了封装的作用,使函数简化了
}

bool InsertNextNode(LNode* p, ElemType e)//指定结点的后插操作
{
	if (p == NULL)
	{
		printf("输入的结点不合法\n");
	}
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)
		printf("申请新结点失败\n");
	s->data = e;
	s->next = p->next;
	p->next = s;
	printf("插入结点成功\n");
}

bool InsertPriorNode(LNode* p, ElemType e)//指定结点的前插操作
{
	if (p == NULL)
		printf("输入的结点不合法\n");
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)
		printf("该结点的内存分配失败\n");
	s->data = p->data;
	s->next = p->next;
	p->next = s;
	p->data = e;
	printf("插入结点成功\n");
}

bool ListDelete(LinkList L, int i, ElemType e)//按位序删除
{
	if(i<1)
	{
		printf("输入的位置不合法\n");
	}
		/*LNode* p;
		int j = 0;
		p = L;
		while (p != NULL && j < i - 1)
		{
			p = p->next;
			j++;
		}*/
	LNode* p = GetElem(L, i - 1);				//再次使用封装
	if (p == NULL)
	{
		printf("输入的位置不合法\n");
	}
	if (p->next == NULL)
	{
		printf("该结点为空,删除失败\n");
	}
	LNode* q = p->next;//令q指向被删除结点
	e = q->data;
	p->next = q->next;
	free(q);
	printf("删除结点成功,该节点的元素是%d", e);
}

bool DeleteNode(LNode* p)//删除指定结点
{
	if (p == NULL)
		printf("输入的结点为空,删除失败\n");
	LNode* q = p->next;
	p->data = q->data;
	p->next = q->next;
	free(q);
	printf("删除结点成功\n");
}             //若p是单链表的最后一个结点,q会出现空指针的错误,则只能引入头结点,依次循环找到p的前一个结点

int length(LinkList L) //求链表表长
{
	int len = 0;
	LNode* p = L;
	while (p->next != NULL)
	{
		p = p->next;
		len++;
	}
	return len;
}

LinkList List_Taillnsert(LinkList L)//用尾插法建立单链表
{
	int len = 0;
	LNode* q = L;
	int x;
	printf("请输入要插入元素的个数:");
	scanf("%d", &x);
	for(int i = 0;i < x ; i++)
	{
		printf("请输入要插入的值:");
		int num;
		scanf("%d", &num);
		InsertNextNode(q, num);
	}
	return L;
}

bool PrintList(LinkList L)//打印链表的元素
{
	LNode* p;
	p = L->next;
	while (p)//直到最后一个结点后停止
	{
		printf("%d ", p->data);
		p = p->next;//使p指向下一个结点
	}
	printf("\n");
}



  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
双向链表 (Doubly Linked List) 是一种常见的数据结构,它的每个结点都有两个指针,分别指向一个结点和后一个结点。这种结构使得双向链表可以在 O(1) 时间内进行插入删除查找操作按位查找双向链表的代码实现如下: ```c++ #include <iostream> using namespace std; struct Node { int val; Node* prev; Node* next; }; class DoublyLinkedList { private: Node* head; Node* tail; public: DoublyLinkedList() { head = tail = nullptr; } void insert(int pos, int val) { Node* newNode = new Node(); newNode->val = val; if (head == nullptr) { head = tail = newNode; return; } if (pos <= 0) { newNode->next = head; head->prev = newNode; head = newNode; return; } Node* cur = head; int i = 0; while (cur != nullptr && i < pos) { cur = cur->next; i++; } if (cur == nullptr) { newNode->prev = tail; tail->next = newNode; tail = newNode; } else { newNode->prev = cur->prev; newNode->next = cur; cur->prev->next = newNode; cur->prev = newNode; } } Node* find(int pos) { if (pos < 0) return nullptr; Node* cur = head; int i = 0; while (cur != nullptr && i < pos) { cur = cur->next; i++; } return cur; } }; int main() { DoublyLinkedList dll; dll.insert(0, 1); dll.insert(1, 2); dll.insert(2, 3); Node* node = dll.find(1); if (node != nullptr) { cout << node->val << endl; } else { cout << "Not found" << endl; } return 0; } ``` 上面的代码中,我们定义了一个 `DoublyLinkedList` 类,其中包含了插入查找操作。在插入操作中,我们首先判断链表是否为空,如果为空,则直接将新结点作为链表头部;否则,我们遍历链表找到插入位置,然后将新结点插入到该位置。 在查找操作中,我们同样遍历链表找到指定位置的结点,并返回该结点的指针。注意,在双向链表中,我们可以从头部或尾部开始遍历,这里我们选择从头部开始遍历。 在主函数中,我们创建了一个双向链表插入了三个结点,并查找了第二个结点,输出结果为 `2`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值