链表的C语言实现之单链表的查找运算
C语言之单链表的插入、删除与查找

C语⾔之单链表的插⼊、删除与查找单链表是⼀种链式存取的数据结构,⽤⼀组地址任意的存储单元存放线性表中的数据元素。
要实现对单链表中节点的插⼊、删除与查找的功能,就要先进⾏的单链表的初始化、创建和遍历,进⽽实现各功能,以下是对单链表节点的插⼊、删除、查找功能的具体实现:#include<stdio.h>#include<stdlib.h>#include<string.h>typedef int ElemType;/***链表通⽤类型*ElemType 代表⾃定义的数据类型*struct Node *next 代表结构体指针(指向下⼀个结构体,完成链表动作)*/typedef struct Node{ElemType data;struct Node *next;}Node;/*==========单链表的初始化================*//**头结点指针数据域设置为空*/void initList(Node **pNode){*pNode=NULL;}/*===========单链表的创建=================*//**功能实现:通过⽤户不断输⼊数据,创建链表*利⽤游标俩个指针(p1,p2),将申请下的数据块(存⼊⽤户输⼊数据),链接起来*/Node *create(Node *pHead){Node *p1;Node *p2;p1=p2=(Node *)malloc(sizeof(Node)); //申请内存空间memset(p1,0,sizeof(Node)); //存⼊数据域清空scanf("%d",&p1->data);p1->next=NULL;while(p1->data>0){ //输⼊负数结束if(pHead==NULL)pHead=p1;elsep2->next=p1;p2=p1;p1=(Node *)malloc(sizeof(Node));memset(p1,0,sizeof(Node));scanf("%d",&p1->data);p1->next=NULL;}return pHead;}/*=================链表的遍历==================*//***从头结点开始,不断遍历出数据域的内容将表遍历*/void printList(Node *pHead){if(NULL==pHead)printf("链表为空\n");else{while(pHead!=NULL){printf("%d ",pHead->data);pHead=pHead->next;}}printf("\n");}/*===============插⼊节点==================*//***Node **pNode 传⼊头结点空间地址*int i 传⼊要插⼊的结点位置*/void insert_data(Node **pNode,int i){Node *temp;Node *target;Node *p;int item;int j=1;printf("输⼊要插⼊的节点值:");scanf("%d",&item);target=*pNode;for(;j<i-1;target=target->next,++j); //不断移动target位置,到要插⼊结点位置,temp=(Node *)malloc(sizeof(Node)); //申请内存空间temp->data=item; //存⼊要存⼊的数据位置p=target->next;target->next=temp;temp->next=p;}/*===============删除节点====================*//***删除结点后,释放内存空间free(temp)*/void delete_data(Node **pNode,int i){Node *target;Node *temp;int j=1;target=*pNode;for(;j<i-1;target=target->next,++j);temp=target->next;target->next=temp->next;free(temp);}/*===============查找结点====================*/int search_data(Node *pNode,int elem){Node *target;int i=1;for(target=pNode;target->data!=elem && target->next!=NULL;++i,target=target->next); if(target->next==NULL)return 0;elsereturn i;}int main(){int i;Node *pHead=NULL;initList(&pHead);pHead=create(pHead);printList(pHead);printf("输⼊插⼊节点位置\n");scanf("%d",&i);insert_data(&pHead,i);printList(pHead);printf("输⼊删除节点位置\n");scanf("%d",&i);delete_data(&pHead,i);printList(pHead);printf("输⼊查找节点\n");scanf("%d",&i);printf("节点所在位置:%d",search_data(pHead,i));return 0;}通过以上各功能的实现,希望对⼤家单链表的学习有所帮助。
C语言单链表实现方法详解

C语⾔单链表实现⽅法详解本⽂实例讲述了C语⾔单链表实现⽅法。
分享给⼤家供⼤家参考,具体如下:slist.h#ifndef __SLIST_H__#define __SLIST_H__#include<cstdio>#include<malloc.h>#include<assert.h>typedef int ElemType;typedef struct Node { //定义单链表中的结点信息ElemType data; //结点的数据域struct Node *next; //结点的指针域}Node,*PNode;typedef struct List { //定义单链表的链表信息PNode first; //first指向单链表中的第⼀个结点PNode last; //last指向单链表中的最后⼀个结点size_t size; //记录单链表中的结点个数}List;void InitList(List *list);//初始化单链表void push_back(List *list, ElemType x);//在单链表的末尾插⼊元素void push_front(List *list, ElemType x);//在单链表的头部插⼊元素void show_list(List *list);//打印单链表void pop_back(List *list);//删除单链表的最后⼀个元素void pop_front(List *list);//删除单链表的第⼀个元素void insert_val(List *list, ElemType val);//将数据元素插⼊到单链表中(要求此时单链表中的数据元素顺序排列)Node* find(List *list, ElemType x);//查找单链表中数据值为x的结点int length(List *list);//求单链表的长度void delete_val(List *list, ElemType x);//按值删除单链表中的某个数据元素void sort(List *list);//对单链表进⾏排序void reverse(List *list);//逆置单链表void clear(List *list);//清除单链表void destroy(List *list);//摧毁单链表#endif //__SLIST_H__slist.cpp#include"slist.h"void InitList(List *list) {list->first = list->last = (Node*)malloc(sizeof(Node)); //头结点assert(list->first != NULL);list->first->next = NULL;list->size = 0;}void push_back(List *list, ElemType x) {//step 1:创建⼀个新的结点Node *s = (Node*)malloc(sizeof(Node));assert(s != NULL);s->data = x;s->next = NULL;//step 2:将新结点插⼊单链表的表尾list->last->next = s;list->last = s;//step 3:更新单链表的长度list->size++;}void push_front(List *list, ElemType x) {//step 1:创建⼀个新的结点Node *s = (Node*)malloc(sizeof(Node));assert(s != NULL);s->data = x;s->next = NULL;//step 2:将新结点插⼊单链表的表头s->next = list->first->next;list->first->next = s;//step 3:判断插⼊的结点是否是单链表的第⼀个结点,若是更新链表的尾指针if (list->size == 0)list->last = s;//step 4:更新单链表的长度list->size++;}void show_list(List *list) {//step 1:指针p指向单链表的第⼀个结点Node *p = list->first->next;//step 2:循环打印结点的信息while (p != NULL) {printf("%d->", p->data);p = p->next;}printf("Nul.\n");}void pop_back(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:定义指针p使其指向⽬标结点的前⼀个结点Node *p = list->first;//从头结点开始while (p->next != list->last)p = p->next;//step 3:删除⽬标结点free(list->last);list->last = p;list->last->next = NULL;//step 4:更新单链表的长度list->size--;}void pop_front(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:定义指针p使其指向⽬标结点的前⼀个结点Node *p = list->first->next;//step 3:删除⽬标结点list->first->next = p->next;free(p);//step 4:判断删除的结点是否是单链表的最后⼀个结点,若是则更新单链表的尾指针 if (list->size == 1)list->last = list->first;//step 4:更新单链表的长度list->size--;}void insert_val(List *list, ElemType x) {//step 1:创建⼀个新的结点Node *s = (Node*)malloc(sizeof(Node));assert(s != NULL);s->data = x;s->next = NULL;//step 2:定义指针p使其指向待插⼊位置的前⼀个结点Node *p = list->first;//从头结点开始while (p->next != NULL && p->next->data < s->data)p = p->next;//step 3:判断结点的待插⼊位置是否是表尾,若是则更新单链表的尾指针if (p->next == NULL)list->last = s;//step 4:插⼊结点s->next = p->next;p->next = s;//step 5:更新单链表长度list->size++;}Node* find(List *list, ElemType x) {//step 1:指针p指向单链表的第⼀个结点Node *p = list->first->next;//step 2:按照循环顺序查找链表结点while (p != NULL && p->data != x)p = p->next;return p;}int length(List *list) {return list->size;}void delete_val(List *list, ElemType x) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:确定结点在单链表中的位置,并判断其是否存在于单链表中Node *p = find(list, x);if (p == NULL) {printf("要删除的数据不存在!\n");return;}//step 3:判断结点位置是否是表尾if (p == list->last)//是表尾pop_back(list);else {//不是表尾Node *q = p->next;p->data = q->data;p->next = q->next;free(q);list->size--;}}void sort(List *list) {//step 1:判断单链表中的结点数是否为0或1if (list->size == 0 || list->size == 1) return;//step 2:将单链表中第⼀个结点之后的链表部分截出,⽅便重新按顺序插⼊链表之中Node *s = list->first->next; // 指针s指向单链表的第⼀个节点Node *p = s->next;//q指向s后⾯的结点list->last = s;//单链表的尾指针指向单链表的第⼀个结点list->last->next = NULL;//截断链表//step 3:将截出的链表中的结点根据其数据域⼤⼩重新插⼊到原来链表中while (p != NULL) {s = p;p = p->next;Node *q = list->first;while (q->next != NULL && q->next->data < s->data)q = q->next;if (q->next == NULL)//判断q此时指向的是否是单链表的最后⼀个结点,若是则更新链表的尾指针list->last = s;//将结点重新插⼊链表s->next = q->next;q->next = s;}}void reverse(List *list) {//step 1:判断单链表中的结点数是否为0或1if (list->size == 0 || list->size == 1) return;//step 2:将单链表中第⼀个结点之后的链表部分截出,然后将截出的链表中的结点按头插法重新插⼊到原链表中 Node *p = list->first->next;Node *q = p->next;list->last = p;list->last->next = NULL;while (q != NULL) {p = q;q = q->next;p->next = list->first->next;list->first->next = p;}}void clear(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:释放单链表中的每⼀个结点Node *p = list->first->next;while (p != NULL) {list->first->next = p->next;free(p);p = list->first->next;}//step 3:头指针和尾指针重新都指向头结点list->last = list->first;//step 4:更新链表长度list->size = 0;}void destroy(List *list) {//step 1:清空单链表clear(list);//step 2:释放头结点free(list->first);//step 3:头指针和尾指针都赋值为空list->first = list->last = NULL;}main.cpp#include"slist.h"void main() {List mylist;InitList(&mylist);ElemType item;Node *p = NULL;int select = 1;while (select) {printf("*******************************************\n"); printf("*[1] push_back [2] push_front *\n");printf("*[3] show_list [4] pop_back *\n");printf("*[5] pop_front [6] insert_val *\n");printf("*[7] find [8] length *\n");printf("*[9] delete_val [10] sort *\n");printf("*[11] reverse [12] clear *\n");printf("*[13*] destroy [0] quit_system *\n"); printf("*******************************************\n"); printf("请选择:>>");scanf("%d", &select);if (select == 0) break;switch (select) {case 1:printf("请输⼊要插⼊的数据(-1结束):>");while (scanf("%d", &item), item != -1) {push_back(&mylist, item);}break;case 2:printf("请输⼊要插⼊的数据(-1结束):>");while (scanf("%d", &item), item != -1) {push_front(&mylist, item);}break;case 3:show_list(&mylist);break;case 4:pop_back(&mylist);break;case 5:pop_front(&mylist);break;case 6:printf("请输⼊要插⼊的数据:>");scanf("%d", &item);insert_val(&mylist, item);break;case 7:printf("请输⼊要查找的数据:>");scanf("%d", &item);p = find(&mylist, item);if (p == NULL)printf("要查找的数据在单链表中不存在!\n"); break;case 8:printf("单链表的长度为%d\n", length(&mylist)); break;case 9:printf("请输⼊要删除的值:>");scanf("%d", &item);delete_val(&mylist, item);break;case 10:sort(&mylist);break;case 11:reverse(&mylist);break;case 12:clear(&mylist);break;//case 13://destroy(&mylist);//break;default:printf("选择错误,请重新选择!\n");break;}}destroy(&mylist); //程序结束,摧毁链表}附:单链表优化版本slist.h#ifndef __SLIST_H__#define __SLIST_H__#include<cstdio>#include<malloc.h>#include<assert.h>typedef int ElemType;typedef struct Node { //定义单链表中的结点信息ElemType data; //结点的数据域struct Node *next; //结点的指针域}Node,*PNode;typedef struct List { //定义单链表的链表信息PNode first; //first指向单链表中的第⼀个结点PNode last; //last指向单链表中的最后⼀个结点size_t size; //记录单链表中的结点个数}List;void InitList(List *list);//初始化单链表void push_back(List *list, ElemType x);//在单链表的末尾插⼊元素void push_front(List *list, ElemType x);//在单链表的头部插⼊元素void show_list(List *list);//打印单链表void pop_back(List *list);//删除单链表的最后⼀个元素void pop_front(List *list);//删除单链表的第⼀个元素void insert_val(List *list, ElemType val);//将数据元素插⼊到单链表中(要求此时单链表中的数据元素顺序排列)Node* find(List *list, ElemType x);//查找单链表中数据值为x的结点int length(List *list);//求单链表的长度void delete_val(List *list, ElemType x);//按值删除单链表中的某个数据元素void sort(List *list);//对单链表进⾏排序void reverse(List *list);//逆置单链表void clear(List *list);//清除单链表void destroy(List *list);//摧毁单链表//代码优化Node* CreateNode(ElemType x); //创建⼀个单链表结点Node* begin(List *list); //返回单链表的第⼀个结点Node* end(List *list); //返回单链表中最后⼀个结点的下⼀个结点void insert(List *list, Node *pos, ElemType x); //在单链表的特定位置(pos)插⼊新的结点#endif //__SLIST_H__slist.cpp#include"slist.h"void InitList(List *list) {list->first = list->last = (Node*)malloc(sizeof(Node)); //头结点assert(list->first != NULL);list->first->next = NULL;list->size = 0;}//push_back的优化void push_back(List *list, ElemType x) {insert(list, end(list), x);}//push_front的优化void push_front(List *list, ElemType x) {insert(list, begin(list), x);}void show_list(List *list) {//step 1:指针p指向单链表的第⼀个结点Node *p = list->first->next;//step 2:循环打印结点的信息while (p != NULL) {printf("%d->", p->data);p = p->next;}printf("Nul.\n");}void pop_back(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:定义指针p使其指向⽬标结点的前⼀个结点Node *p = list->first;//从头结点开始while (p->next != list->last)p = p->next;//step 3:删除⽬标结点free(list->last);list->last = p;list->last->next = NULL;//step 4:更新单链表的长度list->size--;}void pop_front(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:定义指针p使其指向⽬标结点的前⼀个结点Node *p = list->first->next;//step 3:删除⽬标结点list->first->next = p->next;free(p);//step 4:判断删除的结点是否是单链表的最后⼀个结点,若是则更新单链表的尾指针 if (list->size == 1)list->last = list->first;//step 4:更新单链表的长度list->size--;}//insert_val的优化void insert_val(List *list, ElemType x) {//step 1:创建⼀个新的结点Node *s = CreateNode(x);//step 2:定义指针p使其指向待插⼊位置的前⼀个结点Node *p = list->first;//从头结点开始while (p->next != NULL && p->next->data < s->data)p = p->next;//step 3:判断结点的待插⼊位置是否是表尾,若是则更新单链表的尾指针if (p->next == NULL)list->last = s;//step 4:插⼊结点s->next = p->next;p->next = s;//step 5:更新单链表长度list->size++;}Node* find(List *list, ElemType x) {//step 1:指针p指向单链表的第⼀个结点Node *p = list->first->next;//step 2:按照循环顺序查找链表结点while (p != NULL && p->data != x)p = p->next;return p;}int length(List *list) {return list->size;}void delete_val(List *list, ElemType x) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:确定结点在单链表中的位置,并判断其是否存在于单链表中Node *p = find(list, x);if (p == NULL) {printf("要删除的数据不存在!\n");return;}//step 3:判断结点位置是否是表尾if (p == list->last)//是表尾pop_back(list);else {//不是表尾Node *q = p->next;p->data = q->data;p->next = q->next;free(q);list->size--;}}void sort(List *list) {//step 1:判断单链表中的结点数是否为0或1if (list->size == 0 || list->size == 1) return;//step 2:将单链表中第⼀个结点之后的链表部分截出,⽅便重新按顺序插⼊链表之中Node *s = list->first->next; // 指针s指向单链表的第⼀个节点Node *p = s->next;//q指向s后⾯的结点list->last = s;//单链表的尾指针指向单链表的第⼀个结点list->last->next = NULL;//截断链表//step 3:将截出的链表中的结点根据其数据域⼤⼩重新插⼊到原来链表中while (p != NULL) {s = p;p = p->next;Node *q = list->first;while (q->next != NULL && q->next->data < s->data)q = q->next;if (q->next == NULL)//判断q此时指向的是否是单链表的最后⼀个结点,若是则更新链表的尾指针list->last = s;//将结点重新插⼊链表s->next = q->next;q->next = s;}}void reverse(List *list) {//step 1:判断单链表中的结点数是否为0或1if (list->size == 0 || list->size == 1) return;//step 2:将单链表中第⼀个结点之后的链表部分截出,然后将截出的链表中的结点按头插法重新插⼊到原链表中 Node *p = list->first->next;Node *q = p->next;list->last = p;list->last->next = NULL;while (q != NULL) {p = q;q = q->next;p->next = list->first->next;list->first->next = p;}}void clear(List *list) {//step 1:判断单链表是否为空if (list->size == 0) return;//step 2:释放单链表中的每⼀个结点Node *p = list->first->next;while (p != NULL) {list->first->next = p->next;free(p);p = list->first->next;}//step 3:头指针和尾指针重新都指向头结点list->last = list->first;//step 4:更新链表长度list->size = 0;}void destroy(List *list) {//step 1:清空单链表clear(list);//step 2:释放头结点free(list->first);//step 3:头指针和尾指针都赋值为空list->first = list->last = NULL;}//优化Node* CreateNode(ElemType x) {Node *s = (Node*)malloc(sizeof(Node));assert(s != NULL);s->data = x;s->next = NULL;return s;}Node* begin(List *list) {return list->first->next;}Node* end(List *list) {return list->last->next;}void insert(List *list, Node *pos, ElemType x) {//step 1:创建⼀个新的结点Node *s = CreateNode(x);//step 2:确定带插⼊位置Node *p = list->first;while (p->next != pos)p = p->next;//step 3:插⼊结点s->next = p->next;p->next = s;//step 4:判断结点是否插⼊到链表的表尾,若是则更新单链表的表尾指针 if (pos == NULL)list->last = s;//step 5:更新单链表长度list->size++;}main.cpp#include"slist.h"void main() {List mylist;InitList(&mylist);ElemType item;Node *p = NULL;int select = 1;while (select) {printf("*******************************************\n");printf("*[1] push_back [2] push_front *\n");printf("*[3] show_list [4] pop_back *\n");printf("*[5] pop_front [6] insert_val *\n");printf("*[7] find [8] length *\n");printf("*[9] delete_val [10] sort *\n");printf("*[11] reverse [12] clear *\n");printf("*[13*] destroy [0] quit_system *\n");printf("*******************************************\n");printf("请选择:>>");scanf("%d", &select);if (select == 0) break;switch (select) {case 1:printf("请输⼊要插⼊的数据(-1结束):>");while (scanf("%d", &item), item != -1) {push_back(&mylist, item);}break;case 2:printf("请输⼊要插⼊的数据(-1结束):>");while (scanf("%d", &item), item != -1) {push_front(&mylist, item);}break;case 3:show_list(&mylist);break;case 4:pop_back(&mylist);break;case 5:pop_front(&mylist);break;case 6:printf("请输⼊要插⼊的数据:>");scanf("%d", &item);insert_val(&mylist, item);break;case 7:printf("请输⼊要查找的数据:>");scanf("%d", &item);p = find(&mylist, item);if (p == NULL)printf("要查找的数据在单链表中不存在!\n");break;case 8:printf("单链表的长度为%d\n", length(&mylist));break;case 9:printf("请输⼊要删除的值:>");scanf("%d", &item);delete_val(&mylist, item);break;case 10:sort(&mylist);break;case 11:reverse(&mylist);break;case 12:clear(&mylist);break;//case 13://destroy(&mylist);//break;default:printf("选择错误,请重新选择!\n");break;}}destroy(&mylist); //程序结束,摧毁链表}希望本⽂所述对⼤家C语⾔程序设计有所帮助。
数据结构实验报告实现单链表各种基本运算的算法

实验截图(1)void InitList(LinkNode *&L)//初始化线性表{L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点L->next=NULL;//单链表置为空表}void DestroyList(LinkNode *&L)//销毁线性表{LinkNode *pre=L,*p=pre->next;实验截图(2)bool GetElem(LinkNode *L,int i,ElemType &e) //求线性表中第i个元素值{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L;//p指向头结点,j置为0(即头结点的序号为0) while (j<i && p!=NULL)//找第i个结点p{ j++;p=p->next;}if (p==NULL)//存在值为e的结点,返回其逻辑序号ireturn(i);}实验截图(3)bool ListInsert(LinkNode *&L,int i,ElemType e) //插入第i个元素{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L,*s;//p指向头结点,j置为0(即头结点的序号为0) while (j<i-1 && p!=NULL)//查找第i-1个结点p{ j++;p=p->next;}}实验截图(4)编写exp2-2.cpp程序包含有关代码//文件名:exp2-2.cpp#include "linklist.cpp"int main(){LinkNode *h;ElemType e;printf("单链表的基本运算如下:\n");printf(" (1)初始化单链表h\n");InitList(h);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");return 1;}实验截图(5)运行得到结果实验截图(6)。
C语言单链表的基本操作(增删改查)

C语⾔单链表的基本操作(增删改查)这是尾插法单链表,单链表⽐较适合⽤来做队列和栈,因为在链表的头和尾时的增删改查的时间复杂度为O(1),⽽在链表内部的增删改查的平均时间复杂度为O(n)。
#include "stdio.h"#include "stdlib.h"//提供malloc()和free()#include "string.h"#include "time.h"//提供strcpy(),time()等//1.⽤结构体创建链表节点//⼀个⽤来存放数据,另⼀个存放指针struct Node{int data; //数据域struct Node* next; //指针域(指向节点的指针)};//2.全局定义链表头尾指针,⽅便调⽤struct Node* head = NULL;struct Node* end = NULL;//3.向链表添加数据void AddListTill(int a ){//创建⼀个节点struct Node* temp = (struct Node*)malloc(sizeof(struct Node)); //此处注意强制类型转换//节点数据进⾏赋值temp->data = a;temp->next = NULL;//连接分两种情况1.⼀个节点都没有2.已经有节点了,添加到尾巴上if(NULL == head){head = temp;//end=temp;}else{end->next=temp;//end=temp; //尾结点应该始终指向最后⼀个}end=temp; //尾结点应该始终指向最后⼀个}//4.遍历链表并输出void ScanList(){struct Node *temp = head; //定义⼀个临时变量来指向头while (temp != NULL){printf("%d\n",temp->data);temp = temp->next; //temp指向下⼀个的地址即实现++操作}}//5.查找指定的数据是否在链表内struct Node* FindNode(int a ){struct Node *temp = head;while(temp != NULL){if(a == temp->data){return temp;}temp = temp->next;}//没找到return NULL;}//6.删除链表void FreeList(){struct Node *temp = head; //定义⼀个临时变量来指向头while (temp != NULL){struct Node* pt = temp;temp = temp->next; //temp指向下⼀个的地址即实现++操作free(pt); //释放当前}//头尾清空,不然下次的头就接着0x10head = NULL;end = NULL;}//7.在指定位置处插⼊数据void AddListRand(int index,int a){if (NULL == head){printf("链表没有节点\n");return;}struct Node* pt = FindNode(index);if(NULL == pt) //没有此节点{printf("没有指定节点\n");return;}//有此节点//创建临时节点,申请内存struct Node* temp =(struct Node *)malloc(sizeof(struct Node));//节点成员进⾏赋值temp->data = a;temp->next = NULL;//连接到链表上 1.找到的节点在尾部 2.找到的节点在中间if (pt == end){//尾巴的下⼀个指向新插⼊的节点end->next = temp;//新的尾巴end = temp;}else{//先连后⾯(先将要插⼊的节点指针指向原来找到节点的下⼀个) temp->next = pt->next;//后连前⾯pt->next = temp;}}//8.删除链表末尾数据void DeleteListTail(){if (NULL == end){printf("链表为空,⽆需删除\n");return;}//链表不为空//链表有⼀个节点if (head == end){free(head);head = NULL;end = NULL;}else{//找到尾巴前⼀个节点struct Node* temp = head;while (temp->next != end){temp = temp->next;}//找到了,删尾巴//释放尾巴free(end);//尾巴迁移end=temp;//尾巴指针为NULLend->next = NULL;}}//9.删除链表的第⼀个数据void DeleteListHead(){ //记住旧头struct Node* temp = head;//链表检测if (NULL == head){printf("链表为空\n");return;}head = head->next; //头的第⼆个节点变成新的头free(temp);}//10.删除链表指定的数据void DeleteListRand(int a){//链表判断是不是没有东西if(NULL == head){printf("链表没东西\n");return;}//链表有东西,找这个节点struct Node* temp = FindNode(a);if(NULL == temp){printf("查⽆此点\n");return;}//找到了,且只有⼀个节点if(head == end){free(head);head = NULL;end = NULL;}else if(head->next == end) //有两个节点{//看是删除头还是删除尾if(end == temp){DeleteListTail();}else if(temp == head){DeleteListHead();}}else//多个节点{//看是删除头还是删除尾if(end == temp)DeleteListTail();else if(temp == head)DeleteListHead();else//删除中间某个节点{ //找要删除temp前⼀个,遍历struct Node* pt = head;while(pt->next != temp){pt=pt->next;}//找到了//让前⼀个直接连接后⼀个跳过指定的即可 pt->next = temp->next;free(temp);}}}//主函数void main(){struct Node *pFind;srand((unsigned)time(NULL));int i;//创建20个节点for(i = 0; i < 20; i++)AddListTill(i); //添加数据//AddListTill(rand());AddListRand(4,86); //在指定位置4增加节点14//DeleteListHead(); //删除⼀个头结点//DeleteListTail(); //删除⼀个尾结点DeleteListRand(4); //删除4节点ScanList(); //遍历输出链表//FreeList(); //删除链表pFind = FindNode(5); //查找5节点if (pFind != NULL){printf("找到%d\n",pFind->data); //找到节点并且输出该节点数据 }else{printf("No Find!\n");}}以下是排序算法的时间和空间复杂度表:。
数据结构实验报告实现单链表各种基本运算的算法

实验截图(1)void InitList(LinkNode *&L)//初始化线性表{L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点L->next=NULL;//单链表置为空表}void DestroyList(LinkNode *&L)//销毁线性表{LinkNode *pre=L,*p=pre->next;实验截图(2)bool GetElem(LinkNode *L,int i,ElemType &e) //求线性表中第i个元素值{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L;//p指向头结点,j置为0(即头结点的序号为0) while (j<i && p!=NULL)//找第i个结点p{ j++;p=p->next;}if (p==NULL)//存在值为e的结点,返回其逻辑序号ireturn(i);}实验截图(3)bool ListInsert(LinkNode *&L,int i,ElemType e) //插入第i个元素{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L,*s;//p指向头结点,j置为0(即头结点的序号为0) while (j<i-1 && p!=NULL)//查找第i-1个结点p{ j++;p=p->next;}}实验截图(4)编写exp2-2.cpp程序包含有关代码//文件名:exp2-2.cpp#include "linklist.cpp"int main(){LinkNode *h;ElemType e;printf("单链表的基本运算如下:\n");printf(" (1)初始化单链表h\n");InitList(h);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");return 1;}实验截图(5)运行得到结果实验截图(6)。
实现单链表的各种基本运算。

实现单链表的各种基本运算。
单链表是一种常用的数据结构,它由一个头指针和一些节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
单链表具有插入、删除、查找、排序等基本运算。
下面将介绍如何实现单链表的各种基本运算。
1. 创建单链表
首先需要定义一个节点结构,包含数据域和指针域。
然后声明一个头指针,表示单链表的头节点。
接着输入节点数据,逐个创建新节点,并将其插入链表中。
2. 插入节点
在单链表中插入节点有两种情况:插入到链表头部和插入到链表尾部。
插入节点时需要先找到插入位置的前一个节点,然后修改前一个节点的指针域,将其指向新节点,再修改新节点的指针域,将其指向插入位置的后一个节点。
3. 删除节点
在单链表中删除节点也有两种情况:删除链表头部的节点和删除链表任意位置的节点。
删除节点时需要先找到删除位置的前一个节点,然后修改前一个节点的指针域,将其指向待删除节点的后一个节点,最后释放待删除节点的空间。
4. 查找节点
在单链表中查找节点时需要从头节点开始遍历链表,逐个比较节点值,直到找到目标节点或者遍历到链表尾部为止。
5. 排序
单链表排序可以采用冒泡排序、选择排序、快速排序等多种算法。
其中最简单的是冒泡排序,即从头节点开始遍历链表,逐个比较相邻节点的值,如果前一个节点的值大于后一个节点的值,则交换两个节点的值,直到遍历到链表尾部为止。
以上就是单链表的各种基本运算的实现方法,其它高级运算(如合并链表、反转链表等)可以在此基础上进一步扩展。
实验二:单链表基本运算实现

{
int data; //存放表结点值
struct node *next; //存放表结点的直接后驱元素的地址
} ListNode,*LinkList;
//头插法创建初始链表
LinkList create_h(int size)
{
;//将工作指针p指向后一个结点
;//计数器累加
}
return i;
}
//打印链表中的现有元素
printList(LinkList head)
{
LinkList p;
;//将工作指针p指向第1个结点
{
p=(LinkList)malloc(sizeof(ListNode));//申请新结点的存储空间
scanf("%d",&p->data);//读入新结点的值到data域中
;//将新增结点插到头结点的后面
;//将新增结点插到头结点的后面
printf("————头插法建立链表(1)\n");
printf("————尾插法建立链表(2)\n");
printf("————按位查找元素(3)\n");
printf("————按值查找元素(4)\n");
printf("————插入元素(5)\n");
printf("————删除元素(6)\n");
printList(h);
break;
case 5:
printf("插入元素,请输入要插入元素的值:\n");
c++单链表冒泡排序(交换结点),链表增删改查,运算符重载

c++单链表冒泡排序(交换结点),链表增删改查,运算符重载#include <iostream>#include <stdlib.h>#include <time.h>#include <fstream>#include <string>using namespace std;//类class List{public://构造器初始化,⽣成头节点List(){head = new Node;head->next = NULL;}//成员函数void createList();void insertList(int data);void travelList(int chance);void input();int addNode();void deleteData(int addNum);void ifClear();void clearList();//重载下标int operator[](int idx);//重载+friend List operator+(List& List_1, List& List_2);//重载-friend List operator-(List& List_1, List& List_2);//重载<<friend ostream& operator<<(ostream& os, List& list);//重载>>friend istream& operator>>(istream& is, List& list);//冒泡排序void bubbleSortList(List& list);private://数据成员struct Node{int data; //数据域struct Node* next; //指针域} *head;//头指针int num;//链表元素个数};//头插法⽣成节点void List::insertList(int data){Node* cur = new Node;//插⼊数据cur->data = data;//插⼊节点cur->next = head->next;head->next = cur;}//调⽤insertList输⼊数据,⽣成链表void List::input(){cout << "请输⼊链表数量长度:";cin >> num;srand(time(NULL));for (int i = 0; i < num; i++){insertList(rand() % 100);}}//任意位置插⼊节点int List::addNode()int d, idx;cout << "请输⼊你要插⼊的节点数据:";cin >> d;cout << "请输⼊你要插⼊的节点位置: ";cin >> idx;Node* tp = NULL;Node* link = head;//寻找插⼊位置if (idx<1 || idx>num + 1){cout << "操作⾮法" << endl;return num;}else{for (int i = 0; i < idx; i++){tp = link;link = link->next;}Node* cur = new Node;tp->next = cur;cur->data = d;cur->next = link;travelList(1);return ++num;}}ofstream mycout1("D:/text1.txt");ofstream mycout2("D:/text2.txt");//遍历链表并将数据存⼊⽂件void List::travelList(int chance){Node* temp = head->next; //防⽌头指针地址改变while (temp != NULL){cout << temp->data << " ";if (chance == 1)mycout1 << temp->data << " ";elsemycout2 << temp->data << " ";temp = temp->next;}cout << endl;}//删除节点void List::deleteData(int addNum){int i, j = 0;cout << "请问您要删除第⼏个数据: ";cin >> i;Node* tp = NULL;Node* link = head;//link为删除节点后⾯的⼀个节点,temp为删除节点 if (addNum < i || i < 0)cout << "操作⾮法!!" << endl;else{while (link->next){tp = link->next; //第⼀个节点j++;if (i == j) //找的删除的节点{link->next = tp->next;delete tp;break;}link = link->next;}travelList(1);}}//清空链表void List::clearList()Node* tp = NULL;Node* ph = head->next;while (head->next){tp = ph;ph = ph->next;delete tp;head->next = ph;}travelList(1);cout << endl;}//询问是否清空void List::ifClear(){string i;if (!head->next){cout << "链表已清空" << endl; }else{cout << "是否清空链表(是/否):";cin >> i;if (i == "是"){clearList();cout << "链表清空完成" << endl; }elsecout << "链表未清空" << endl; }}//冒泡排序void List::bubbleSortList(List& list){//求list链表长度lenint len=0;//临时指针pheadNode* phead = list.head->next;while (phead){len++;phead = phead->next;}//冒泡排序for (int i=0;i<len-1; i++){//phead指向头结点phead = list.head;//ph1指向⾸元结点Node* ph1 = phead->next;//ph2指向⾸元结点的后继Node* ph2 = ph1->next;//进⼊循环冒出最⼤的数for (int j = 0; j < len - 1 - i; j++){//如果前⾯的值⼤于后⾯的值则交换if (ph1->data > ph2->data){phead->next = ph2;ph1->next = ph2->next;ph2->next = ph1;//结点交换后,ph1与ph2位置颠倒回来 Node* temp = ph1;ph1 = ph2;ph2 = temp;}//如果不需要交换,三指针移动phead = phead->next;ph1 = ph1->next;ph2 = ph2->next;}//打印结点数据phead = list.head->next;while (phead){cout << phead->data << " ";phead = phead->next;}cout << endl;}//下标重载int List::operator[](int idx){//临时指针temp,为了防⽌头指针改变Node* temp = head;//如果下标⼩于链表长度进⾏取值if (idx < num){for (int i = 0; i < idx; i++){temp = temp->next;}}return temp->data;}//+ 重载List operator +(List & List_1, List & List_2){//由链表1⽣成链表3List List_3;//⽣成临时指针temp_1List::Node* temp_1 = List_1.head->next;//把链表1的值给链表3while (temp_1){List_3.insertList(temp_1->data);temp_1 = temp_1->next;}//⽣成临时指针temp_2List::Node* temp_2 = List_2.head->next;//把链表2的值给链表3while (temp_2){List_3.insertList(temp_2->data);temp_2 = temp_2->next;}return List_3;}//- 重载List operator -(List & List_1, List & List_2){//⽣成链表4List List_4;//⽣成临时指针temp_1,temp_2List::Node* temp_1 = List_1.head->next;List::Node* temp_2 = List_2.head->next;//flag为1链表2有链表1的值,为0则没有int flag = 0;//⽐较链表⼀和链表⼆,不等就将数据存⼊List_4 while (temp_1){//临时指针temp_2回溯temp_2 = List_2.head->next;while (temp_2){//判断是否有相同值if (temp_1->data == temp_2->data){flag = 1;break;}//指针移动temp_2 = temp_2->next;}//没有相同值List_4则插⼊数据if (!flag){List_4.insertList(temp_1->data);//指针移动,开始下⼀轮对⽐temp_1 = temp_1->next;flag = 0;}return List_4;}//重载<<ostream& operator<<(ostream & os, List & list) {list.bubbleSortList(list);return os;}//重载>>istream &operator>>(istream & is, List & list) {int size, i=0;cout << "(输⼊链表长度):";is >> size;//当i<size时录⼊数据while (i < size){int data;is >> data;//插⼊数据list.insertList(data);i++;}return is;}int main(){//初始化,⽣成List_1List List_1;//输⼊链表长度List_1.input();//遍历链表,并存⼊text1⽂件List_1.travelList(1);//添加节点并返回总结点数int addNum = List_1.addNode();//删除节点List_1.deleteData(addNum);//初始化,⽣成List_2List List_2;//输⼊链表长度List_2.input();//遍历链表,并存⼊text2⽂件List_2.travelList(2);//重载下标cout << "取链表2的第⼆个元素:";cout << List_2[2]<<endl;//重载+List List_3;List_3 = List_1 + List_2;cout << "两链表+为:";List_3.bubbleSortList(List_3);//重载-List List_4;List_4 = List_1 - List_2;cout << "两链表-为:";List_4.bubbleSortList(List_4);//重载<<cout << "cout<<List_4:";cout << List_4 << endl;//重载>>List List_5;cout << "cin>>List_5";cin >> List_5;cout << "链表List_5: " << List_5;//询问是否清空链表1List_1.ifClear();//关闭打开的⽂件mycout1.close();mycout2.close();return 0;}⽤类创建单链表时,可以将结构体封装为私有成员,在构造函数中初始化链表极为⽅便;链表的删除操作需要先进⾏遍历,并且遍历途中不能随意改变头结点的位置,所以在进⾏链表的操作时,皆需要临时变量防⽌头指针改变;除此之外,在进⾏冒泡排序时,需要画图理清逻辑,虽然⽐较过后,链表的连接⽅式改变了,但是ph1与ph2位置颠倒,需要互换回来,使下⼀次⽐较正常运⾏;运算符“+”号重载时,如果直接由链表1⽣成链表3,在进⾏减操作时,会发现链表1随链表3的改变⽽改变了,导致在进⾏“-”操作时出错,后在“+”操作时,对链表3进⾏逐⼀赋值,问题得到解决。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
以下是应用查找算法的一个例子:
#include<stdio.h>
#include<malloc.h>
#include<string.h>/*包含一些字符串处理函数的头文件*/
建立了一个单链表之后,如果要进行一些如插入、删除等操作该怎么办?所以还须掌握一些单链表的基本算法,来实现这些操作单链表的基本运算包括:查找、插入和删除下面我们就一一介绍这三种基本运算的算法,并结合我们建立单链表的例子写出相应的程序
1、查找
对单链表进行查找的思路为:对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回null
{
printf(\"不能分配内存空间!\");
exit(0);
}
h->namቤተ መጻሕፍቲ ባይዱ[0]=\'\\0\';
h->link=null;
p=h;
for(i=0;i<n;i++)
{
if((s= (stud *) malloc(sizeof(stud)))==null)
{
printf(\"不能分配内存空间!\");
exit(0);
}
p->link=s;
printf(\"请输入第%d个人的姓名\",i+1);
scanf(\"%s\",s->name);
s->link=null;
p=s;
}
return(h);
}
stud * search(stud *h,char *x) /*查找链表的函数,其中h指针是链表的表头指针,x指针是要查找的人的姓名*/
number=n;
head=creat(number);
printf(\"请输入你要查找的人的姓名:\");
scanf(\"%s\",fullname);
searchpoint=search(head,fullname); /*调用查找函数,并把结果赋给searchpoint指针*/
}
return(p); /*返回与所要查找结点的地址*/
else p=p->link;
}
if(p==null)
printf(\"没有查找到该数据!\");
}
main()
{
int number;
char fullname[20];
stud *head,*searchpoint; /*head是表头指针,searchpoint是保存符合条件的结点地址的指针*/
#define n 10
typedef struct node
{
char name[20];
struct node *link;
}stud;
stud * creat(int n) /*建立链表的函数*/
{
stud *p,*h,*s;
int i;
if((h=(stud *)malloc(sizeof(stud)))==null)
{
stud *p; /*当前指针,指向要与所查找的姓名比较的结点*/
char *y; /*保存结点数据域内姓名的指针*/
p=h->link;
while(p!=null)
{
y=p->name;
if(strcmp(y,x)==0) /*把数据域里的姓名与所要查找的姓名比较,若相同则返回0,即条件成立*/