链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
其实数据结构的结构是次要的,数据结构的思想才是最重要的,只有懂得了思想才能写出适合自己的结构,每个链表的结构都有可能是不一样的,随具体的问题来定,比如说单链表,一般结点都大致相同,都是一个元素和一个指向下一个结点的指针。但是链表的结构却不尽相同,有的只有一个称为Head的头结点,而有的还有一个叫做Tail的尾结点,还有的结构里面还维护了一个现在结点数目的变量number。虽然结构可以根据具体情况不尽相同,但是对于对于结构的增删查改的操作确实相似的。
下面是我实现的一种单链表。
头文件:SList.h
#ifndef _SLIST_H
#define _SLIST_H
#include<iostream>
using namespace std;
#define ElemType int
typedef struct Node
{
ElemType data;
struct Node *next;
}Node, *PNode;
typedef struct SList
{
PNode first; //头结点之后的第一个结点
PNode last; //最后一个结点
size_t size; //结点个数
}SList;
//////////////////////////////////////////
void InitSList(SList *list); //初始化函数
void push_front(SList *list, ElemType x); //头插
void push_back(SList *list, ElemType x); //尾插
void show_list(SList *list);
Node* find(SList *list, ElemType key); //查找
void delete_val(SList *list,ElemType key); //按值删除
//////////////////////////////////////////
#endif
函数实现:SList.cpp
#include"SList.h"
void InitSList(SList *list)
{
Node *s = (Node *)malloc(sizeof(Node)); //头结点
s->next = NULL;
list->first = list->last = s;
list->size = 0;
}
void push_front(SList *list, ElemType x)
{
Node *s = (Node *)malloc(sizeof(Node));
s->data = x;
if(list->first == list->last)
{
list->last = s;
}
s->next = list->first->next;
list->first->next = s;
list->size++;
}
void push_back(SList *list, ElemType x)
{
Node *s = (Node *)malloc(sizeof(Node));
s->data = x;
s->next = NULL;
list->last->next = s;
list->last = s;
list->size++;
}
void show_list(SList *list)
{
Node *p = list->first->next;
while(p != NULL)
{
cout<<p->data<<"-->";
p = p->next;
}
cout<<"Over!"<<endl;
}
Node* find(SList *list, ElemType key)
{
Node *p = list->first->next;
while(p!=NULL && p->data!=key)
{
p = p->next;
}
return p;//
}
void delete_val(SList *list,ElemType key)
{
Node *q = find(list,key);
if(q == NULL)
{
cout<<"要删除的值不存在!"<<endl;
return;
}
Node *p = list->first;
while(p->next != q)
{
p = p->next;
}
if(q == list->last)
{
list->last = p;
}
p->next = q->next;
free(q);
q = NULL;
list->size--;
}
测试主函数:Main.cpp
#include"SList.h"
void main()
{
SList mylist;
InitSList(&mylist);
Node *p = NULL;
ElemType Item;
int select = 1;
while(select)
{
cout<<"*********************************"<<endl;
cout<<"*[1] push_back [2] push_front *"<<endl;
cout<<"*[3] show_list [0] quit_system*"<<endl;
cout<<"*[4] pop_back [5] pop_front *"<<endl;
cout<<"*[6.] delete_pos [7] delete_val *"<<endl;
cout<<"*[8.] insert_pos [9] insert_val *"<<endl;
cout<<"*[10] find [11]updata_pos *"<<endl;
cout<<"*[12] sort [13]reverse *"<<endl;
cout<<"*[14] length [15]clear_list *"<<endl;
cout<<"*[16] destroy [17]remove_all *"<<endl;
cout<<"*********************************"<<endl;
cout<<"请选择:>";
cin>>select;
switch(select)
{
case 1:
cout<<"请输入要插入的数据(-1结束):>";
while(cin>>Item,Item!=-1)
{
push_back(&mylist,Item);
}
break;
case 2:
cout<<"请输入要插入的数据(-1结束):>";
while(cin>>Item,Item!=-1)
{
push_front(&mylist,Item);
}
break;
case 3:
show_list(&mylist);
break;
case 7:
cout<<"请输入要删除的值:>";
cin>>Item;
delete_val(&mylist,Item);
break;
case 10:
cout<<"请输入要查找的值:>";
cin>>Item;
p = find(&mylist,Item);
if(p == NULL)
{
cout<<"要查找的元素不存在!"<<endl;
}
break;
default:
break;
}
}
}