[c语言]单链表的实现

来源:互联网 发布:mac运行速度变慢 编辑:程序博客网 时间:2024/05/19 23:15

一、基础知识:链表(线性表的链式存储结构)

(1)特点:逻辑关系相邻,物理位置不一定相邻。

(2)分类:

     a.不带头节点

    b.带头节点

           wKiom1cd_6ijVRHJAAAaP1x2gqE446.png

(3)单链表的存储结构:

typedef struct SListNode{ DataType data; struct SListNode* next;}SListNode;

 

二、代码实现(因避开使用二级指针,所以代码中使用了c++中的引用):此处构造的为不带头节点的链表

方法一:

(1)sList.h

 #pragma oncetypedef int DataType;typedef struct SListNode{ DataType data; struct SListNode* next;}SListNode;void PushBack(SListNode* & pHead, DataType d);void PopBack(SListNode* & pHead);void PushFront(SListNode* & pHead, DataType d);void PopFront(SListNode* & pHead);void PrintList(SListNode* pHead);SListNode* Find(SListNode* & pHead, DataType d);void Insert(SListNode* & pos, DataType d);

(2)sList.cpp

#include <stdio.h>#include <malloc.h>#include <assert.h>#include "sList.h"SListNode* MakeNode(DataType d){ SListNode* tmp = (SListNode*)malloc(sizeof(SListNode)); tmp->data = d; tmp->next = NULL; return tmp;}void PushBack(SListNode* & pHead, DataType d){ //1.空 //2.不空 if(pHead == NULL) {  pHead = MakeNode(d); } else {  //先找尾,再插入新节点  SListNode* tail = pHead;  while(tail->next != NULL)  {   tail = tail->next;  }  tail->next = MakeNode(d); }}void PopBack(SListNode* & pHead){ //1.空 //2.一个节点 //3.多个节点 if(pHead == NULL) {  return; } else if (pHead->next == NULL) {  free(pHead);  pHead = NULL; } else {  SListNode* tail = pHead;  SListNode* prev = NULL;  while(tail->next != NULL)  {   prev = tail;   tail = tail->next;  }  prev->next = NULL;  free(tail); }}void PushFront(SListNode* & pHead, DataType d){ if(pHead == NULL) {  pHead = MakeNode(d); } else {  SListNode* tmp = pHead;  pHead = MakeNode(d);  pHead->next = tmp; }}void PopFront(SListNode* & pHead){ if(!pHead) {  printf("List is empty!");  return; } else {  SListNode* tmp = pHead;  pHead = pHead->next;  free(tmp); }}SListNode* Find(SListNode* & pHead, DataType d){ SListNode* find = pHead; while(find) {  if(find->data == d)   return find;  find = find->next; } return NULL;}void Insert(SListNode* & pos, DataType d){ assert(pos); /* 方法一: SListNode* tmp = MakeNode(d); tmp->next = pos->next; pos->next = tmp; */ //方法二: SListNode* next = pos->next; pos->next = MakeNode(d); pos->next->next = next;}void Erase(SListNode*& pHead,SListNode* & pos){ assert(pos&&pHead); SListNode* prev = pHead; while(prev->next != pos) {  prev = prev->next; } prev->next = pos->next; free(pos); pos = NULL;}void PrintList(SListNode* pHead){ SListNode* tmp = pHead; while(tmp) {  printf("%d->", tmp->data);  tmp = tmp->next; } printf("NULL\n");

(3)test.cpp

#include "sList.h"#include <stdio.h>#include <stdlib.h>void test1(){ //不带头节点 SListNode* list = NULL; PushBack(list, 1); PushBack(list, 2); PushBack(list, 3); PushBack(list, 4);// PushFront(list,0);// PopFront(list);// PopBack(list); SListNode* ret = Find(list, 2); if(ret == NULL) {  printf("No Exist!\n");  return; }// Insert(ret, 4); Erase(list,ret); PrintList(list);}int main(){ test1(); system("pause"); return 0;

 方法二:

这种方法定义了两个结构体,方便以后对链表的操作,你可以在LinkList这个结构体中加入尾指针或者长度等等信息,来使操作更加简单。

typedef struct ListNode    //单链表的一个结点{DataType data;struct ListNode* next;}ListNode,*pListNode; 
typedef struct LinkList   //链表的信息                                                                                            {pListNode pHead;}LinkList,*pLinkList;

 

源文件:

1.LinkList.h

#ifndef __LINKLIST_H__#define __LINKLIST_H__#include <stdio.h>#include <stdlib.h>#include <assert.h>typedef int DataType;typedef struct ListNode{DataType data;struct ListNode* next;}ListNode,*pListNode;typedef struct LinkList{pListNode pHead;}LinkList,*pLinkList;void InitLinkList(pLinkList plist);void DestoryLinkList(pLinkList plist);void PushBack(pLinkList plist, DataType x);void PopBack(pLinkList plist);void PushFront(pLinkList plist, DataType x);void PopFront(pLinkList plist);void PrintLinkList(pLinkList plist);pListNode Find(pLinkList plist, DataType x);void Insert(pLinkList plist, pListNode pos, DataType x);void Remove(pLinkList plist, DataType x);void RemoveAll(pLinkList plist, DataType x);void Erase(pLinkList plist, pListNode pos);void BubbleSort(pLinkList plist);#endif


 

2.LinkList.c

#include "LinkList.h"void InitLinkList(pLinkList plist){assert(plist);plist->pHead = NULL;}void DestoryLinkList(pLinkList plist){pListNode cur = NULL;assert(plist);cur = plist->pHead;while(cur){pListNode del = cur;cur = cur->next;free(del);del = NULL;}plist->pHead = NULL;}pListNode BuyNode(DataType x) //创建一个结点{pListNode newNode = (pListNode)malloc(sizeof(ListNode));if(NULL == newNode){printf("out of memory!");exit(0);}newNode->data = x;newNode->next = NULL;return newNode;}void PushBack(pLinkList plist, DataType x){pListNode cur = NULL;pListNode newNode = NULL;assert(plist);cur = plist->pHead;newNode = BuyNode(x);if(NULL == cur)   //空链表{plist->pHead = newNode;}else              //链表不为空{while(cur->next != NULL){cur = cur->next;}cur->next = newNode;}}void PopBack(pLinkList plist){pListNode cur = NULL;assert(plist);cur = plist->pHead;if(NULL == cur)    //链表为空{printf("LinkList is Empty\n");}else if(NULL == cur->next) //链表只有一个结点{free(cur);cur = NULL;plist->pHead = NULL;}else    //链表有两个及以上结点{while(cur->next->next != NULL){cur = cur->next;}free(cur->next);cur->next = NULL;}}void PushFront(pLinkList plist, DataType x){pListNode newNode = NULL;assert(plist);newNode = BuyNode(x);newNode->next = plist->pHead;plist->pHead = newNode;}void PopFront(pLinkList plist){assert(plist);if(NULL == plist->pHead){printf("LinkList is Empty\n");return;}else{pListNode del = plist->pHead;plist->pHead = del->next;free(del);del = NULL;}}void PrintLinkList(pLinkList plist){pListNode cur = NULL;assert(plist);cur = plist->pHead;while(cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}pListNode Find(pLinkList plist, DataType x){pListNode cur = NULL;assert(plist);cur = plist->pHead;while(cur){if(cur->data == x){return cur;}cur = cur->next;}return NULL;}void Insert(pLinkList plist, pListNode pos, DataType x) //在pos之前插入{pListNode newNode = NULL;assert(plist);assert(pos);newNode = BuyNode(x);if(pos == plist->pHead){PushFront(plist, x);}else{pListNode cur = plist->pHead;while(cur->next != pos){cur = cur->next;}cur->next = newNode;newNode->next = pos;}}void Remove(pLinkList plist, DataType x)  //删除数据为x的结点{pListNode pos = NULL;assert(plist);pos = Find(plist, x);if(pos == NULL){printf("no find\n");}else if(pos == plist->pHead){PopFront(plist);}else{pListNode cur = plist->pHead;while(cur->next != pos){cur = cur->next;}cur->next = pos->next;free(pos);pos = NULL;}}void RemoveAll(pLinkList plist, DataType x){pListNode cur = NULL;assert(plist);cur = plist->pHead;if(plist->pHead == NULL)//空链表{return;}else if(plist->pHead->next == NULL)  //只有一个结点{free(cur);cur = NULL;plist->pHead =NULL;return;}while(cur->data == x)  //头{pListNode del = cur;cur = cur->next;plist->pHead = cur;free(del);del = NULL;}while(cur && cur->next)                  //中间和尾{if(cur->next->data == x){pListNode del = cur->next;cur->next = del->next;free(del);del = NULL;}cur = cur->next;}}void Erase(pLinkList plist, pListNode pos){assert(pos);assert(plist);if(pos == plist->pHead){PopFront(plist);}else{pListNode cur = plist->pHead;while(cur->next != pos){cur = cur->next;}cur->next = pos->next;free(pos);pos = NULL;}}void BubbleSort(pLinkList plist){int flag = 0;pListNode cur = NULL;   //控制外循环排序的趟数pListNode log= NULL;   //记录内循环上一次交换的最后一个数pListNode cmp = NULL;  //记录内循环的当前比较值assert(plist);log = plist->pHead;cur = plist->pHead;while(log){log = log->next;}while(cur->next != NULL){pListNode node = NULL;cmp = plist->pHead;log = node;flag = 0;while(cmp->next!=log){if(cmp->data > cmp->next->data){DataType tmp = cmp->data;cmp->data = cmp->next->data;cmp->next->data = tmp;node = cmp;flag = 1;}cmp = cmp->next;}if(flag == 0){return;}cur = cur->next;}}


 

3.Test.c

#include "LinkList.h"void Test1(){LinkList list;InitLinkList(&list);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);PrintLinkList(&list);PopBack(&list);PrintLinkList(&list);PopBack(&list);PopBack(&list);PopBack(&list);PopBack(&list);PopBack(&list);PrintLinkList(&list);DestoryLinkList(&list);}void Test2(){LinkList list;InitLinkList(&list);PushFront(&list, 1);PushFront(&list, 2);PushFront(&list, 3);PushFront(&list, 4);PushFront(&list, 5);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);PopFront(&list);PrintLinkList(&list);DestoryLinkList(&list);}void Test3(){LinkList list;InitLinkList(&list);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);PrintLinkList(&list);//Insert(&list, Find(&list, 4), 3);Insert(&list, Find(&list, 1), 3);Insert(&list, Find(&list, 5), 3);PrintLinkList(&list);DestoryLinkList(&list);}void Test4(){LinkList list;InitLinkList(&list);PushBack(&list, 4);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);PushBack(&list, 4);PrintLinkList(&list);//Remove(&list, 1);//Remove(&list, 5);//Remove(&list, 3);RemoveAll(&list, 4);PrintLinkList(&list);DestoryLinkList(&list);}void Test5(){LinkList list;InitLinkList(&list);PushBack(&list, 4);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);PushBack(&list, 4);PrintLinkList(&list);Erase(&list,Find(&list,3));PrintLinkList(&list);BubbleSort(&list);PrintLinkList(&list);DestoryLinkList(&list);}int main(){//Test1();//Test2();//Test3();//Test4();Test5();system("pause");return 0;}


 

0 0
原创粉丝点击