C语言双向链表

FindItem中查找是双向开始的,这里要考虑链表节点的奇偶情况。

DeteleMax中要考虑链表中只有一项的情况。

AddItem中分为两种情况:第一次插入和后面插入。

1、函数的接口:list.h

#ifndef LIST_H_
#define LIST_H_

#include<stdbool.h>

typedef struct node {
	struct node* last;
	int item;
	struct node* next;
}Node;

typedef struct link {
	Node* head;
	Node* end;
}Link;

/*初始化          */
void InitiList(Link* plink);

/*判断内存是否已满*/
bool ListIsFull(void);

/*在末尾end插入    */
bool AddItem(Link* plink, int item);

/*寻找数字item      */
bool FindItem(const Link* plink, int item);

/*遍历链表          */
void Traverse(const Link* plink, void(*pfun)(int item));

/*删除所有节点      */
bool DeleteAll(Link* plink);

/*删除最大项        */
void DeleteMax(Link* plink);

#endif

2、函数的实现:list.cpp

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include "list.h"


void InitiList(Link* plink)
{
	plink->end = NULL;
	plink->head = NULL;
}

bool ListIsFull(void)
{
	Node* p;
	p = (Node*)malloc(sizeof(Node));
	if (p == NULL) {
		printf("内存不足!\n");
		return false;
	}
	free(p);
	return true;
}

/*在末尾end插入*/
bool AddItem(Link* plink, int item)
{
	if (ListIsFull() == false)
		return false;

	Node* New;

	New = (Node*)malloc(sizeof(Node));  /*第一次已经判断,不会为NULL*/
	New->item = item;

	if (plink->head == NULL){
		New->last = NULL;
		New->next = NULL;
		plink->end = New;
		plink->head = New;
		return true;
	}
	else {
		New->next = NULL;
		New->last = plink->end;
		plink->end->next = New;
		plink->end = New;
	}

	return true;
}

bool FindItem(const Link* plink, int item)
{
	Node* del;
	Node* head = plink->head;
	Node* end = plink->end;
	while (end != NULL && head != NULL){
		if (head->item == item) {
			del = head;
			return true;
		}
		if (end->item == item) {
			del = end;
			return true;
		}

		if ((head->next == end) || (head == end)) {  //节点数为偶数时,节点为奇数时
			return false;
		}

		end = end->last;
		head = head->next;
	}
	return false;
}

void Traverse(const Link* plink, void(*pfun)(int item))
{
	if (plink->head == NULL) {
		printf("空链表!\n");
	}
	Node* scan = plink->head;
	while (scan != NULL) {
		(*pfun)(scan->item);
		scan = scan->next;
	}
}

bool DeleteAll(Link* plink)
{
	Node* old;

	while (plink->head != NULL){
		old = plink->head;
		plink->head = plink->head->next;
		free(old);
	}
	return true;
}

void DeleteMax(Link* plink)
{
	Node* head = plink->head;
	Node* end = plink->end;
	Node* max = head;
	while (end != NULL && head != NULL) {
		if (head->item > max->item) {
			max = head;
		}
		if (end->item > max->item) {
			max = end;
		}
		if ((head->next == end) || (head == end)) {  
			break;
		}
		end = end->last;
		head = head->next;
	}
	if (max == plink->head) {
		plink->head = max->next;
		if (max->next != NULL) {  
			max->next->last = max->last;
		}
		else {   //如果只有一项时
			plink->end = NULL;
		}
		free(max);
		return;
	}
	if (max == plink->end) {
		plink->end = max->last;
		max->last->next = max->next;
		free(max);
		return;
	}
	max->last->next = max->next;
	max->next->last = max->last;
	free(max);
}

3、运行程序:链表.cpp

#include<stdio.h>
#include<stdbool.h>
#include"list.h"

void show(int n);

int main()
{
	int n;
	Link list;
	InitiList(&list);

	printf("输入数字则插入\n输入0则退出插入\n");
	while (1) {
		scanf_s("%d", &n);
		if (n == 0)
			break;
		AddItem(&list, n);
	}
	printf("输出输入的链表:\n");
	Traverse(&list, show);

	printf("\n输入n并查找是否有n:\n");
	scanf_s("%d", &n);
	if (FindItem(&list, n) == true) {
		printf("存在n:%d\n", n);
	}
	else {
		printf("不存在n:%d\n", n);
	}

	printf("删除最大一项后再输出\n");
	DeleteMax(&list);
	
	Traverse(&list, show);

	DeleteAll(&list);

}

void show(int n)
{
	printf("%-5d", n);
}

4、运行结果

One has to adapt to survive.

想要生存,就要学会适应。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值