#include #include #include /* 要求编写的函数如下: InitList(Node *pHead) *pHead必须具有,单链表必须有head。如果没有用不了,具有操作意义 :初始化单链表* DestroyList(Node *pHead) :销毁单链表* ClearList(Node *pHead) //除了头结点都删除掉 :清空单链表 ListEmpty(Node *pHead) :判断单链表是否为空 ListLength(Node *pHead) :获取单链表中节点个数 GetElem(Node *pHead, int index, Node *pElem)Node *pHead头指针。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) :遍历单链表中所有节点* */ /************************************************************************/ #define KLen 30//单链表的长度 int g_iCount = 0; /*编写一个单链表,每个节点就是一条信息,每条信息包含的内容如下: 姓名:name 联系方式:phone*/ typedef struct tagNode { char name[KLen]; char phone[KLen]; struct tagNode *pNext; }Node;//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));//为什么要强制转换成(Node *),因为不转换会成为void *类型的 if(*pHead == NULL)//一级指针,先把head+next都设置成NULL { return 0; } (*pHead)->pNext = NULL;//单链表的结构 [值(value) 地址(pNext )]===一个元素 return 1;//设置初始化后,返回1 } void ClearList(Node *pHead)//注意,不清空头结点. { Node *pCurrentNode = NULL; Node *pNextNode = NULL; if(pHead->pNext != NULL)//如果头结点的next不等于null的话,意思是头结点的下一个元素不为null的话, { pCurrentNode = pHead->pNext;//就赋值 while(pCurrentNode != NULL)//只要有值,就一直循环 { pNextNode = pCurrentNode->pNext;//赋值 free(pCurrentNode);//释放内存 pCurrentNode = pNextNode;//再找head的下下个来做 } } } 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)//如果count为0的话,代表是为空,就返回是的1 { return 1; } return 0; } int ListLength(Node *pHead) { return g_iCount; } void ListTraverse(Node *pHead)//遍历 { Node *pCurrentNode = pHead->pNext;//head的下一个元素 while(pCurrentNode != NULL)//head的下一个元素不为null { printf("姓名:%s ", pCurrentNode->name);//输出输出 printf("电话:%s ", pCurrentNode->phone); printf("\n"); pCurrentNode = pCurrentNode->pNext;//在指向head的下一个元素的下一个元素,一直循环到没有下一个元素为止 } printf("\n\n"); } int GetElem(Node *pHead, int index, Node *pElem) { int count = 0; if(index < 0 || index > g_iCount)//如果索引index小于0或者单链表长度小于索引的长度 { return 0; } Node *pCurrentNode = pHead; while(pCurrentNode != NULL) { if(count == index)//如果找到了就赋值给pElem,然后输出 { 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))//看是不是相等函数,看name+phone与传入的是否相等 {// return index; } pCurrentNode = pCurrentNode->pNext;//继续next 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));//申请内存(Node *)强制转换成这个,不然会返回无类型.void *. if(pNode == NULL) { return 0; } //拷贝 strcpy(pNode->name, pElem->name); strcpy(pNode->phone, pElem->phone); pCurrentNode = pHead; while(pCurrentNode != NULL) { if(count == index)//0==0 { /*这段话的根本意思是:0代表head的下一个位置。也就是1.因为head是固定的 保存head指向下一个结点的指针。head的下一个元素是要放进来的哪个元素 然后是把放进去的哪个元素的next指向原来的1的位置上的元素 */ //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;//如果没有找到要插入的位置,继续next } 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--;//删除一个节点,所以要--1 return 1; } count++; pPreNode = pCurrentNode; pCurrentNode = pCurrentNode->pNext; } return 1; }
C语言单链表(实现全部函数)
关注
打赏