02、单链表LinkList

LinkList.h

#pragma once
typedef int DataType;
typedef struct Node {
	DataType data;
	struct Node* next;
}ListNode,*LinkList;

/*
定义方式:
线性表的链式存储,是采用一组任意的存储单元存放线性表的元素
除了存储元素本身的信息外,还要存储一个指示其直接后继元素的信息(直接后继元素的地址)。
这两个部分构成的存储结构称为节点(node)。即节点包含两个域:数据域和指针域。
通过指针域将线性表中n个节点元素按照逻辑顺序链在一起就构成了链表
LinkList L; 
ListNode * L;
*/

void InitList(LinkList* head);/*初始化单链表*/
int ListEmpty(LinkList head);
ListNode* GetNode(LinkList head, int i);
ListNode* LocateElem(LinkList head, DataType e);
int LocatePos(LinkList head, DataType e);
int InsertList(LinkList head, int i, DataType e);
int DeleteList(LinkList head, int i, DataType *e);
int ListLength(LinkList head);
void DestoryList(LinkList head);
int DelElem(LinkList A, LinkList B);

void PrintList(LinkList head);

LinkList.cpp

#include"LinkList.h"
#include"cstdlib"
#include"cstdio"
void InitList(LinkList* head)/*初始化单链表*/
{
	if ((*head = (LinkList)malloc(sizeof(ListNode))) == NULL) {
		/*为头节点分配空间*/
		exit(-1);
	}
	(*head)->next = NULL;/*将头节点的指针域置空*/
}
int ListEmpty(LinkList head)/*单链表为空,返回1,否则,返回0*/ {
	if (head->next == nullptr) {
		return 1;
	}
	else {
		return 0;
	}
}
ListNode* GetNode(LinkList head, int i) {
	ListNode *p;
	int j;
	if (ListEmpty(head) == 1) /*链表为空,返回NULL*/
		return NULL;
	
	if (i < 1) /*序号不合法,返回NULL*/
		return NULL;
	j = 0;
	p = head;
	while (p->next != NULL && j < i) {
		p = p->next;
		j++;
	}
	if (j == i) {
		return p;
	}	
	else {
		return NULL;
	}
		

}
ListNode* LocateElem(LinkList head, DataType e)
/*按内容查找单链表中元素值为e的元素,
成功则返回对应元素的节点指针,否则返回NULL表示失败*/
{
	ListNode* p;
	p = head->next;
	while (p) {
		if (p->data != e) {
			p = p->next;
		}
		else {
			break;
		}
	}
	return p;
}
int LocatePos(LinkList head, DataType e)
/*按内容查找单链表中元素值为e的元素,
成功则返回对应元素的序号,否则返回0表示查找失败*/
{
	ListNode* p;
	int i;
	if (ListEmpty(head) == 1) {
		return 0;
	}
	p = head->next;
	i = 1;
	while (p) {
		if (p->data != e) {
			p = p->next;
			i++;
		}
		else {
			return i;
		}

	}
	if (!p) {/*如果没有找到和e相等的元素,返回0*/
		return 0;
	}
}
int InsertList(LinkList head, int i, DataType e) 
/*在链表第i个位置插入一个结点,结点的元素值为e,插入成功返回1,失败返回0*/ {
	ListNode* pre, * p;
	/*定义第i个元素的前驱结点指针是pre,指针p指向新生成的节点*/
	int j;
	pre = head;
	j = 0;
	while (pre->next != NULL && j < i - 1) 
	/*找到第i-1个节点,即i位置的前驱节点*/
	{
		pre = pre->next;
		j++;
	}
	if (j != i - 1) {
		printf("插入的位置错误\n");
		return 0;
	}
	/*新生成一个节点,并将e赋值给该节点的数据域*/
	if ((p = (ListNode*)malloc(sizeof(ListNode))) == NULL)
		exit(-1);
	p->data = e;

	/*插入结点的操作*/
	p->next = pre->next;
	pre->next = p;
	return 1;
}
int DeleteList(LinkList head, int i, DataType *e)
/*删除单链表中的第i个位置的结点,删除成功返回1,失败返回0*/
{
	ListNode *pre, *p;
	int j;
	pre = head;
	j = 0;
	while (pre->next != NULL && pre->next->next != NULL && j < i - 1) 
	/*判断是否找到前驱结点*/
	{
		pre = pre->next;
		j++;
	}
	if (j != i - 1)
	{
		printf("删除位置有误\n");
		return 0;
	}
	/*指针p指向单链表中的第i个结点,并将该结点的数据域复制给e*/
	p = pre->next;
	*e = p->data;

	/*删除结点*/
	pre->next = p->next;
	free(p);

}
int ListLength(LinkList head) {
	ListNode* p;
	p = head;
	int count = 0;
	while (p)
	{
		p = p->next;
		count++;
	}
	return count;
}
void DestoryList(LinkList head) {
	ListNode *p,*q;
	p = head;
	while (p) {
		q = p;
		p = p->next;
		free(q);
	}
}

int DelElem(LinkList A, LinkList B)
{
	int i, pos;
	DataType e;
	ListNode* p;
	/*单链表中,取出每个元素和A中的元素比较,如果相等,则删除A中的结点*/
	for (i = 1; i <= ListLength(B); i++) {
		p = GetNode(B, i);
		if (p) {
			pos = LocatePos(A, p->data);
			if (pos > 0)
				DeleteList(A, pos, &e);
		}
	}
	return 0;
}


void PrintList(LinkList head)
{
	ListNode* p;
	p = head->next;
	while (p) {
		printf("%4d", p->data);
		p = p->next;
	}
	printf("\n");
}

单链表在内存中的一个情况:

单链表去重: 

 

void TestLinkList_Dele() {
    int i;
    DataType a[] = { 8,17,21,25,27,29 };
    DataType b[] = { 3,8,9,21,26,27 };
    LinkList A, B;

    InitList(&A);
    InitList(&B);
    for (i = 1; i <= sizeof(a) / sizeof(a[0]); i++) {
        InsertList(A, i, a[i - 1]);
    }
    for (i = 1; i <= sizeof(b) / sizeof(b[0]); i++) {
        InsertList(B, i, b[i - 1]);
    }
    printf("链表A:\n");
    PrintList(A);
    printf("链表B:\n");
    PrintList(B);

    DelElem(A, B);
    printf("去重后的A:\n");
    PrintList(A);
 
}

 合并链表

void MergeList(LinkList A, LinkList B, LinkList C)
{
	ListNode* pa,*pb;
	pa = A->next;
	pb = B->next;
	int i = 1;
	while (pa && pb) {
		if (pa->data < pb->data) {
			InsertList(C, i, pa->data);
			pa = pa->next;
		}
		else {
			InsertList(C, i, pb->data);
			pb = pb->next;
		}
				
		i++;
	}
	while (pa) { /*pa 还有剩余*/
		InsertList(C, i, pa->data);
		pa = pa->next;
		i++;
	}
	while (pb) { /*pb还有剩余*/
		InsertList(C, i, pb->data);
		pb = pb->next;
		i++;
	}


}

头插法反转链表

void ReverseList(LinkList head,LinkList out)
{
	ListNode* p;
	p = head->next;
	while (p) {
		InsertList(out, 1, p->data);
		p = p->next;
	}
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要建立一个单链表(linklist),首先需要定义一个节点结构体,该结构体包含一个数据域和一个指向下一个节点的指针域。 例如: ``` struct Node { int data; // 数据域 struct Node* next; // 指针域 }; ``` 接下来,可以使用该节点结构体来创建链表。 步骤如下: 1. 定义一个头节点,并将其指针域指向空。 2. 定义一个指向当前节点的指针cur,并将cur指向头节点。 3. 通过循环依次创建链表的节点,并将cur的指针域指向新建节点。 4. 当所有节点都创建完毕后,最后一个节点的指针域应该指向空。 5. 链表建立完成后,可以通过遍历链表的方式访问其中的节点。 例如,我们要创建一个包含5个节点的链表: ```cpp struct Node { int data; struct Node* next; }; int main() { // 定义头节点 struct Node* head = NULL; // 定义当前节点指针 struct Node* cur = NULL; // 创建第一个节点 struct Node* node1 = (struct Node*)malloc(sizeof(struct Node)); node1->data = 1; node1->next = NULL; // 将头节点指向第一个节点 head = node1; cur = node1; // 创建剩余的节点 for (int i = 2; i <= 5; i++) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = i; newNode->next = NULL; // 将当前节点的指针域指向新节点 cur->next = newNode; // 移动当前节点指针 cur = newNode; } // 遍历链表并输出节点值 cur = head; while (cur != NULL) { printf("%d ", cur->data); cur = cur->next; } // 释放链表的内存空间 cur = head; while (cur != NULL) { struct Node* temp = cur; cur = cur->next; free(temp); } return 0; } ``` 以上代码中,通过循环创建了包含5个节点的链表,并遍历输出了链表中的节点值。最后,通过循环释放链表的内存空间,防止内存泄漏。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值