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