C++ 数据结构 线性链表

  • #pragma once 减少头文件组合,降低编译出错的概率
  • 作用等效于 
#ifndef FUNC_H
#define FUNC_H代码主体#endif

线性表的定义

  • 排队问题 
  • 简单的线性表 (物理 或者逻辑结构)
  • 1,数组
  • 2,链表

  • 线性表相关操作:
  • 1,线性表初始化
  • 2,线性表遍历
  • 3,线性表插入元素
  • 4,线性表删除元素

代码

#include <stdio.h>
#include <stdlib.h>#define KSIZE 10
#define FALSE 0
#define TRUE 1/************************************************************************/
/* 线性表(linear list)
线性表是一个相当灵活的数据结构,它的长度可以根据需要增长和缩短,即对线性表的数据元素不仅可以进行访问,还可以进行插入和删除等。
抽象定义的线性表如下:
ADT:Abstract Data Type 抽象数据类型ADT LISTL:LIST简称,即线性表本身
i:索引
e:element简称,即元素
cur_:current简称,即当前元素
pre_:previous简称,即前一个元素
next_:next,即下一个元素
visit:对元素访问的方式InitList(&L)                  :初始化线性表
DestroyList(&L)               :销毁线性表
ClearList(&L)                 :清空线性表
ListEmpty(L)                  :线性表是否为空
ListLength(L)                 :线性表中元素个数
GetElem(L, i, &e)             :获取线性表中指定的元素
LocateElem(L, e, compare())   :给定元素获取第一次出现的索引位置
PriorElem(L, cur_ e, &pre_ e) :给定元素获取其前一个元素
NextElem(L, cur_ e, &next_ e) :给定元素获取其后一个元素
ListInsert(&L, i, e)          :将元素插入链表中指定位置
ListDelete(&L, i, &e)         :从链表中指定位置删除元素
ListTraverse(L, visit())      :遍历元素简单线性表--C语言实现线性表组成类型:int数组*//************************************************************************/
/*---------------------------------------
InitList(&L);
DestroyList(&L);
ClearList(&L);
ListEmpty(L);
ListLength(L);
GetElem(L, i, &e);
LocateElem(L, e, compare());
ListInsert(&L, i, e);
ListDelete(&L, i, &e);
ListTraverse(L, visit());PriorElem(L, cur_ e, &pre_ e);
NextElem(L, cur_ e, &next_ e);
-----------------------------------------*/int count;void InitList(int *list);
void DestroyList(int *list);
void ClearList(int *list);
int ListEmpty(int *list);
int ListLength(int *list);
int GetElem(int *list, int i, int *e);
int LocateElem(int *list, int e);
int ListInsert(int *list, int i, int e);
int ListDelete(int *list, int i, int *e);
void ListTraverse(int *list);int main(void)
{int arr[KSIZE];int e = 0;InitList(arr);ListInsert(arr, 0, 5);ListInsert(arr, 0, 8);ListInsert(arr, 1, 7);ListTraverse(arr);ListDelete(arr, 0, NULL);ListTraverse(arr);GetElem(arr, 1, &e);printf("e = %d\n", e);printf("5的索引是%d\n", LocateElem(arr, 5));ClearList(arr);if(ListEmpty(arr)){printf("线性表为空\n");}else{printf("线性表不为空\n");}printf("线性表的长度为%d\n", ListLength(arr));DestroyList(arr);system("pause");return 0;
}void InitList(int *list)
{int i = 0;count = 0;for(i = 0; i < KSIZE; i++){list[i] = 0;}
}void DestroyList(int *list)
{}void ClearList(int *list)
{int i = 0;count = 0;for(i = 0; i < KSIZE; i++){list[i] = 0;}
}int ListEmpty(int *list)
{if(count == 0){return TRUE;}else{return FALSE;}
}int ListLength(int *list)
{return count;
}int GetElem(int *list, int i, int *e)
{if(i < count && i >= 0){*e = list[i];return TRUE;}else{return FALSE;}
}int LocateElem(int *list, int e)
{int i = 0;for(i = 0; i < count; i++){if(list[i] == e){return i;}}return -1;
}/************************************************************************/
/*-------------------------| 0 | 1 | 2 | 3 | 4 |   |-------------------------
*/
/************************************************************************/
int ListInsert(int *list, int i, int e)
{if(i <= count && i >= 0){/*int tempArr[KSIZE] = {0};int k = 0;int j = 0;int m = 0;for(k = 0; k < i; k++){tempArr[j++] = list[k];}tempArr[i] = e;j++;for(k = i; k < count ; k++){tempArr[j++] = list[k];}count++;for(m = 0; m < count; m++){list[m] = tempArr[m];}*/int k = 0;for(k = count-1; k >= i; k--){list[k+1] = list[k];}list[i] = e;count++;return TRUE;}else{return FALSE;}
}int ListDelete(int *list, int i, int *e)
{if(i < count && i >= 0){int k = 0;if(e != NULL){*e = list[i];}for(k = i; k < count - 1; k++){list[k] = list[k+1];}count--;return TRUE;}else{return FALSE;}
}void ListTraverse(int *list)
{int i = 0;for(i = 0; i < count; i++){printf("%d ", list[i]);}printf("\n");
}

堆申请内存

#include <stdio.h>
#include <stdlib.h>#define KSIZE 10
#define FALSE 0
#define TRUE 1/************************************************************************/
/* 线性表(linear list)
线性表是一个相当灵活的数据结构,它的长度可以根据需要增长和缩短,即对线性表的数据元素不仅可以进行访问,还可以进行插入和删除等。
抽象定义的线性表如下:
ADT:Abstract Data Type 抽象数据类型ADT LISTL:LIST简称,即线性表本身
i:索引
e:element简称,即元素
cur_:current简称,即当前元素
pre_:previous简称,即前一个元素
next_:next,即下一个元素
visit:对元素访问的方式InitList(&L)                  :初始化线性表
DestroyList(&L)               :销毁线性表
ClearList(&L)                 :清空线性表
ListEmpty(L)                  :线性表是否为空
ListLength(L)                 :线性表中元素个数
GetElem(L, i, &e)             :获取线性表中指定的元素
LocateElem(L, e, compare())   :给定元素获取第一次出现的索引位置
PriorElem(L, cur_ e, &pre_ e) :给定元素获取其前一个元素
NextElem(L, cur_ e, &next_ e) :给定元素获取其后一个元素
ListInsert(&L, i, e)          :将元素插入链表中指定位置
ListDelete(&L, i, &e)         :从链表中指定位置删除元素
ListTraverse(L, visit())      :遍历元素简单线性表--C语言实现线性表组成类型:int数组*//************************************************************************/
/*---------------------------------------
InitList(&L);
DestroyList(&L);
ClearList(&L);
ListEmpty(L);
ListLength(L);
GetElem(L, i, &e);
LocateElem(L, e, compare());
ListInsert(&L, i, e);
ListDelete(&L, i, &e);
ListTraverse(L, visit());PriorElem(L, cur_ e, &pre_ e);
NextElem(L, cur_ e, &next_ e);
-----------------------------------------*/int count{};
int size{};//分配的内存空间void InitList(int *list);
void DestroyList(int *list);
void ClearList(int *list);
int ListEmpty(int *list);
int ListLength(int *list);
int GetElem(int *list, int i, int *e);
int LocateElem(int *list, int e);
int ListInsert(int *list, int i, int e);
int ListDelete(int *list, int i, int *e);
void ListTraverse(int *list);int main(void)
{int arr[KSIZE];int e = 0;InitList(arr);ListInsert(arr, 0, 5);ListInsert(arr, 0, 8);ListInsert(arr, 1, 7);ListTraverse(arr);ListDelete(arr, 0, NULL);ListTraverse(arr);GetElem(arr, 1, &e);printf("e = %d\n", e);printf("5的索引是%d\n", LocateElem(arr, 5));ClearList(arr);if(ListEmpty(arr)){printf("线性表为空\n");}else{printf("线性表不为空\n");}printf("线性表的长度为%d\n", ListLength(arr));DestroyList(arr);system("pause");return 0;
}void InitList(int *list)
{int i = 0;count = 0;size = KSIZE;//在堆上申请内存list = reinterpret_cast<int *>(malloc(sizeof (int) * KSIZE));if (list == nullptr){return ;}for(i = 0; i < KSIZE; i++){list[i] = 0;}
}void DestroyList(int *list)
{free(list);list = nullptr;
}void ClearList(int *list)
{int i = 0;count = 0;for(i = 0; i < KSIZE; i++){list[i] = 0;}
}int ListEmpty(int *list)
{if(count == 0){return TRUE;}else{return FALSE;}
}int ListLength(int *list)
{return count;
}int GetElem(int *list, int i, int *e)
{if(i < count && i >= 0){*e = list[i];return TRUE;}else{return FALSE;}
}int LocateElem(int *list, int e)
{int i = 0;for(i = 0; i < count; i++){if(list[i] == e){return i;}}return -1;
}/************************************************************************/
/*-------------------------| 0 | 1 | 2 | 3 | 4 |   |-------------------------
*/
/************************************************************************/
int ListInsert(int *list, int i, int e)
{if(i <= count && i >= 0){int k = 0;if (count == size){size = 2 * count;list = static_cast<int *>(realloc(list, size));}if (list == nullptr){return FALSE;}for(k = count-1; k >= i; k--){list[k+1] = list[k];}list[i] = e;count++;return TRUE;}else{return FALSE;}
}int ListDelete(int *list, int i, int *e)
{if(i < count && i >= 0){int k = 0;if(e != NULL){*e = list[i];}for(k = i; k < count - 1; k++){list[k] = list[k+1];}count--;return TRUE;}else{return FALSE;}
}void ListTraverse(int *list)
{int i = 0;for(i = 0; i < count; i++){printf("%d ", list[i]);}printf("\n");
}

单链表

代码

#include <stdio.h>
#include <stdlib.h>/************************************************************************/
/* 要求:定义一个结构体Node,结构体由两个整数组成,第一个是val,第二个是next定义一个Node类型的数组,数组有3个Node节点,3个Node节点的关系如下:nodeA(5, 2)  nodeB(7, -1)  nodeC(8, 1)数组首元素nodeA为头结点,编写函数ListTraverse遍历此链表*/
/************************************************************************/typedef struct tagNode
{int val;int next;
}Node;void ListTraverse(Node *pList);int main(void)
{Node list[3] = {{5,2},{7,-1},{8,1}};ListTraverse(list);system("pause");return 0;
}void ListTraverse(Node *pList)
{int i = 0;Node *pCurrentNode = &pList[i];while(pCurrentNode->next != -1){printf("%d  ", pCurrentNode->val);i = pCurrentNode->next;pCurrentNode = &pList[i];}printf("%d  \n", pCurrentNode->val);
}

链表

/************************************************************************/
/* by 袁春旭                                                                  */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>/************************************************************************/
/* 要求:编写一个单链表,每个节点就是一条信息,每条信息包含的内容如下:姓名:name联系方式:phone要求编写的函数如下:InitList(Node *pHead)                               :初始化单链表*DestroyList(Node *pHead)                            :销毁单链表*ClearList(Node *pHead)                              :清空单链表ListEmpty(Node *pHead)                              :判断单链表是否为空ListLength(Node *pHead)                             :获取单链表中节点个数GetElem(Node *pHead, int index, Node *pElem)        :获取单链表中指定的节点LocateElem(Node *pHead, Node *pElem)                :给定节点获取单链表中第一次出现的索引位置ListInsert(Node *pHead, int index, Node *pElem)     :将节点插入单链表中指定位置*ListDelete(Node *pHead, int index, Node *pElem)     :从单链表中指定位置删除节点*ListTraverse(Node *pHead)                           :遍历单链表中所有节点*作业:PriorElem(Node *pHead, Node *pCurElem, Node *pPreElem)  :获取给定节点的前一个节点NextElem(Node *pHead, Node *pCurElem, Node *pNextElem)  :获取给定节点的后一个节点打造自己的通讯录1. 设计通讯录菜单(如:插入信息,查找信息)2. 扩展节点信息3. 回顾文件读写知识提示:1. 使用记事本保存信息2. 编写函数将信息从文件中逐一读出并按条写入链表节点3. 编写函数将链表各个节点逐一写入文件,达到保存的目的4. 注意读写函数的调用时机:在程序运行之初加载文件。在用户执行退出菜单时保存文件。
*/
/************************************************************************/#define KLen 30int g_iCount = 0;typedef struct tagNode
{char name[KLen];char phone[KLen];struct tagNode *pNext;
}Node;int InitList(Node **pHead);
void ClearList(Node *pHead);
void DestroyList(Node *pHead);
int ListEmpty(Node *pHead);
int ListLength(Node *pHead);
void ListTraverse(Node *pHead);
int GetElem(Node *pHead, int index, Node *pElem);
int LocateElem(Node *pHead, Node *pElem);
int ListInsert(Node *pHead, int index, Node *pElem);
int ListDelete(Node *pHead, int index, Node *pElem);int main(void)
{//单元测试Node *pList = NULL;Node node1 = {"Jim", "1234", NULL};Node node2 = {"Merry", "4321", NULL};Node node3 = {"James", "3456", NULL};Node node4;InitList(&pList);ListInsert(pList, 0, &node1);printf("%d \n", ListLength(pList));ListInsert(pList, 1, &node2);ListInsert(pList, 1, &node3);printf("%d \n", ListEmpty(pList));printf("%d \n", ListLength(pList));ListTraverse(pList);ListDelete(pList, 2, NULL);printf("%d \n", ListLength(pList));ListTraverse(pList);DestroyList(pList);system("pause");return 0;
}int InitList(Node **pHead)
{*pHead = (Node *)malloc(sizeof(Node));if(*pHead == NULL){return 0;}(*pHead)->pNext = NULL;return 1;
}void ClearList(Node *pHead)
{Node *pCurrentNode = NULL;Node *pNextNode = NULL;if(pHead->pNext != NULL){pCurrentNode = pHead->pNext;while(pCurrentNode != NULL){pNextNode = pCurrentNode->pNext;free(pCurrentNode);pCurrentNode = pNextNode;}}
}void DestroyList(Node *pHead)
{ClearList(pHead);free(pHead);pHead = NULL;
}int ListEmpty(Node *pHead)
{/*if(pHead->pNext == NULL){return 1;}else{return 0;}*/if(g_iCount == 0){return 1;}return 0;
}int ListLength(Node *pHead)
{//int count = 0;//Node *pCurrentNode = pHead->pNext;//while(pCurrentNode != NULL)//{//	count++;//	//printf("姓名:%s   ", pCurrentNode->name);//	//printf("电话:%s   ", pCurrentNode->phone);//	pCurrentNode = pCurrentNode->pNext;//}//return count;return g_iCount;
}void ListTraverse(Node *pHead)
{Node *pCurrentNode = pHead->pNext;while(pCurrentNode != NULL){printf("姓名:%s   ", pCurrentNode->name);printf("电话:%s   ", pCurrentNode->phone);printf("\n");pCurrentNode = pCurrentNode->pNext;}printf("\n\n");
}int GetElem(Node *pHead, int index, Node *pElem)
{int count = 0;if(index < 0 || index > g_iCount){return 0;}Node *pCurrentNode = pHead;while(pCurrentNode != NULL){if(count == index){pElem = pCurrentNode;return 1;}count++;pCurrentNode = pCurrentNode->pNext;}return 1;
}int LocateElem(Node *pHead, Node *pElem)
{int index = 1;Node *pCurrentNode = pHead->pNext;while(pCurrentNode != NULL){if(!strcmp(pCurrentNode->name, pElem->name)&& !strcmp(pCurrentNode->phone, pElem->phone)){return index;}pCurrentNode = pCurrentNode->pNext;index++;}return -1;
}int ListInsert(Node *pHead, int index, Node *pElem)
{int count = 0;Node *pNode = NULL;Node *pCurrentNode = NULL;if(index < 0 || index > g_iCount){return 0;}pNode = (Node *)malloc(sizeof(Node));if(pNode == NULL){return 0;}strcpy(pNode->name, pElem->name);strcpy(pNode->phone, pElem->phone);pCurrentNode = pHead;while(pCurrentNode != NULL){if(count == index){//1. 将当前节点的next指针保存Node *pTemp = pCurrentNode->pNext;//2. 让当前节点的next指针指向申请的内存pCurrentNode->pNext = pNode;//3. 将保存的next指针赋值给新节点的next指针pNode->pNext = pTemp;g_iCount++;return 1;}count++;pCurrentNode = pCurrentNode->pNext;}return 1;
}int ListDelete(Node *pHead, int index, Node *pElem)
{int count = 0;Node *pCurrentNode = pHead;Node *pPreNode = NULL;if(index <= 0 || index > g_iCount){return 0;}while(pCurrentNode != NULL){if(count == index){//1. 使currentNode的上一个节点指向currentNode的下一个节点pPreNode->pNext = pCurrentNode->pNext;if(pElem != NULL){//将要删除的节点数据拷贝出来strcpy(pElem->name, pCurrentNode->name);strcpy(pElem->phone, pCurrentNode->phone);}//2. 删除currentNode指向的节点free(pCurrentNode);g_iCount--;return 1;}count++;pPreNode = pCurrentNode;pCurrentNode = pCurrentNode->pNext;}return 1;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

英语口语 week12 Thursday

英语文章 As the pace of life quickens with technological advancements, people are occupied by all kinds of trivial matters. They seem forever on the go. There’s no difficulty in imagining that the hustle and bustle of everyday life can make us lose focus…

H.264/AVC视频编解码技术详解 第一章 视频信息与压缩编码

H.264/AVC视频编解码技术详解系列笔记 是对 H.264/AVC视频编解码技术详解 课程的学习 文章目录人与世界的交互视频信号的表示方法视频压缩编码视频信息为什么可以被压缩&#xff1f;视频压缩编码的分类&#xff1a;视频压缩编码的基本技术人与世界的交互 从远古时代开始&#…

英语口语 week13 Monday

英语文章 Competitions between businesses can be very aggressive in contemporary society. However, the competition for talented personnel is thought to be the key to business competition. Wise employers consider their employees as the company’s core asset…

文件系统的由来

启蒙篇 文件的由来 磁盘上保存的是一对十六进制的数据&#xff0c;如何切分数据形成不同的文件&#xff0c;也就是如何确定一个文件的起始和终止位置&#xff1f;将相关数据打包在一起形成一个文件&#xff0c;比如从什么位置开始到什么位置结束&#xff0c;是一张图片、一段…

英语口语 week13 Wednesday

英语文章 Despite his extraordinary success in writing fairy tales,Hans Christian Andersen preferred to living in a way of simplicity and frugality. He often wore an old hat when he went out. One day, a well-dressed man stopped Andersen on the street, inte…

操作系统 IO管理

学什么&#xff1f; I/O input / output 输入&#xff1a;鼠标 键盘 手柄 触摸屏 摄像头 MTC 扫描仪输出&#xff1a;显示器 打印机 耳机 音响 既是输入也是输出&#xff1a;光驱 网卡 磁盘 U盘硬件&#xff1a;设备如何把数据返回到PC机&#xff0c;但是不同种类的设…

c++面向对象高级编程 学习九 pointer-like classes

c的class设计出来有两种形式&#xff0c;一种像指针&#xff0c;一种像函数 智能指针里包含普通指针&#xff0c;要写 * 和 -> 的函数 sp->method(); //sp-> 经 T* operator*() const 函数&#xff0c;得到px //由于 箭头符号&#xff08;->&#xff09;作用下去…

const int *a和int*const a 的区别详解

补充知识 “const int i”与“int const i”之间的区别对变量来说&#xff0c;const 关键字可以限定一个变量的值不允许改变&#xff0c;从而保护被修饰的东西&#xff0c;防止意外修改&#xff0c;在一定程度上可以提高程序的安全性和可靠性。 代码 const int * int i1 10…

c++面向对象高级编程 学习十 function-like classes

本节是设计一个class&#xff0c;使它的行为像一个函数。 如果一个东西能接受小括号()操作符&#xff0c;那么这个东西就称之为函数&#xff0c;或像函数的东西。 下图为三个函数对()的重载&#xff0c;这三个类均为像函数的类&#xff0c;它们可接受()操作符&#xff0c; 标…

英语口语 Week14 Monday

英语文章 Thailand, a country in Southeast Asia with an area of about 514,000 square kilometers, has been increasingly prosperous in its tourism industry in the past few decades. Its capital is Bangkok and its major languages are Thai, Chinese and English.…

c++面向对象高级编程 学习十一 类模板、函数模板、成员模板

namespace经验谈&#xff1a; 团队中函数或类的名字可能会冲突&#xff0c;因此使用namespace进行区分。 类模板&#xff1a; template<typename T> 函数模板&#xff1a; template<class T>&#xff0c;此处class可改成typename 函数模板在使用的时候&#xff0…

操作系统面试 总结

以下文章来源于程序员cxuan &#xff0c;作者cxuan 原文链接什么是操作系统 操作系统是管理硬件和软件的一种应用程序。操作系统是运行在计算机上最重要的一种软件&#xff0c;它管理计算机的资源和进程以及所有的硬件和软件。它为计算机硬件和软件提供了一种中间层&#xff…

英语口语week 14 Thursday

英语文章 A couple decided to go out to celebrate their wedding anniversary, so they called a babysitter. When the babysitter arrived, the two children had already been asleep. The babysitter soon got bored and went to the kitchen where she blended some wh…

c++面向对象高级编程 学习十二 模板

模板特化&#xff1a; 模板是一种泛化的形式&#xff0c;特化是将参数类型进行指定&#xff0c;写出特化的版本&#xff0c;当在调用下图cout<<hash()(1000);的时候&#xff0c;由于特化中有struct hash{ }的版本&#xff0c;因此会直接调用特化部分。 模板偏特化&…

英语口语 week14 Friday

英语文章 Shopping is taking place every second. However, the prices of the same goods may differ from store to store. A name-brand dress may cost several hundred pounds at a boutique, but only half the price in a discount store or a big chain store. Moreo…

数据结构 树

定义 树是节点的优先集合度&#xff1a;孩子的数量&#xff0c;度为0 就是终端节点&#xff0c;不为零就是根节点有序树&#xff1a;有顺序&#xff0c;不可以替换无序树&#xff1a;无顺序&#xff0c;可以替换深度 和 树的深度相反&#xff0c;第一层深度为1 树的深度为 3 二…

英语口语 Week15 TuesDay

英语文章 One day, when Bella was doing sports in the school yard, the squirrel fled out of her sleeve. Threading its way through a considerable number of people, the squirrel disappeared in the distance After a sequence of movements, it hopped onto the ar…

c++面向对象高级编程 学习十四 引用

文章目录referencereference的常见用途reference 变量有三种形式&#xff1a;值&#xff0c;指针&#xff0c;引用 int x0; //值 int* p&x;//指向整型的指针&#xff0c;地址&#xff0c;指针在之后的程序中可以指向其他变量 int& rx;//引用&#xff0c;此处表示 r代…

google浏览器 隐藏功能开启

网址 chrome://flags/ 1&#xff0c;多线程下载 2&#xff0c;暗黑模式3&#xff0c;标签缩略图4&#xff0c;PWA 渐进式web应用 网页即应用5&#xff0c;阅读模式&#xff0c;排除广告&#xff0c;点击阅读模式去除干扰chrome://net-internals6&#xff0c;解决有问题的代理IP…

英语口语Week 15 Wednesday

英语文章 Accomplishing the task assigned by the teacher; Julia rushed out. Squatting at the gate and playing with the squirrel, Bella waved at the sight of Julia and yelled out here" . Julia ran quickly towards them, pointed at the squirrel and asked…