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;
}
}