链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作。
循环链表
循环链表是与单链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个结点的指针是指向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。
循环链表的运算与单链表的运算基本一致。所不同的有以下几点:
1、在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为NULL。此种情况还使用于在最后一个结点后插入一个新的结点。
2、在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到表尾。而非象单链表那样判断链域值是否为NULL。
双向链表
双向链表其实是单链表的改进。
当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
手写链条篇
单链表结构体
typedef struct student
{
int data;
struct student *next;
}node;
建立单链表
node *create()
{
node *head,*p,*s;
int x,cycle=1;
head=(node*)malloc(sizeof(node)); //建立头节点
p=head;
while(cycle)
{
printf("\nPlease input the data:");
scanf("%d",&x);
if(x!=0)
{
s=(node*)malloc(sizeof(node));//每次新建一个节点
s->data=x;
printf("\n%d",s->data);
p->next=s;
p=s;
}
else
{
cycle=0;
}
}
head=head->next;
p->next=NULL;
printf("\n yyy %d",head->data);
return (head);
}
单链表测长
int length(node *head)
{
int n=0;
node *p;
p=head;
while(p!=NULL)
{
p=p->next;
n++;
}
return (n);
}
单链表输出
void print(node *head)
{
node *p;
int n;
n=length(head);
printf("\nNow,These %d records are :\n",n);
p=head;
if(head!=NULL)
p=p->next;
while(p!=NULL)
{
printf("\n uuu %d ",p->data);
p=p->next;
}
}
单链表删除节点
node *remove(node *head ,int num)
{
node *p1,*p2;
p1=head;
while(num!=p1->data && p1->next!=NULL)//查找data为num的节点
{
p2=p1;
p1=p1->next;
}
if(num==p1->data) //如果存在num节点,则删除
{
if(p1==head)
{
head=p1->next;
free(p1);
}
else
{
p2->next=p1->next;
}
}
else
{
printf("\n%d could not been found",num);
}
return (head);
}
单链表的插入
node *sort(node *head)
{
node *p,*p2,*p3;
int n;
int temp;
n=length(head);
if(head==NULL ||head->next==NULL)//如果只有一个或者没有节点
return head;
p=head;
for(int j=1;j<n;++j)
{
p=head;
for(int i=0;i<n-j;++i)
{
if(p->data > p->next->data)
{
temp=p->data;
p->data=p->next->data;
p->next->data=temp;
}
p=p->next;
}
}
return (head);
}
单链表的逆置
node *reverse(node *head)
{
node *p1,*p2,*p3;
if(head==NULL || head->next==NULL)
return head;
p1=head;
p2=p1->next;
while(p2)
{
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->next=NULL;
head=p1;
return head;
}
综合版
#include<iostream>
#include<string.h>
#include<cstdlib>
using namespace std;
typedef struct lnode
{
int data;
lnode *next;
}lnode,*linklist;
int m;
int listinsert(linklist &l,int i,int e)//在带头节点的单链表中第i个元素插入元素e
{
int j=0;
linklist p,s;
p=new lnode;
p=l;
s=new lnode;
while(p&&j<i-1)p=p->next,j++;
if(!p||j>i-1)return 0;
s->data=e;
s->next=p->next;
p->next=s;
return 1;
}
int listdelete(linklist &l,int i)//在带头节点的单链表中删除第i个元素e,并返回其值
{
int j=0;
linklist p;
p=new lnode;
p=l;
while(p->next&&j<i-1)p=p->next,j++;
if(!(p->next)||j>i-1)return 0;
linklist q;
q=new lnode;
q=p->next;
p->next=q->next;
m=q->data;
free(q);
return 1;
}
void createlist_tou(linklist &l,int n)//头插法
{
l=new lnode;
l->next=NULL;
linklist p;
cout<<"请输入单链表:";
for(int i=n;i>0;i--)
{
p=new lnode;
cin>>p->data;
p->next=l->next;
l->next=p;
}
}
void display(linklist &l)
{
linklist p;
p=l->next;
cout<<"链表为:";
while(p!=NULL){cout<<p->data<<" ";p=p->next;}
cout<<endl;
}
int main()
{
linklist l;
int a,i,e;
cout<<"请输入链表长度:";
cin>>a;
createlist_tou(l,a);
display(l);
cout<<"输入插入位置:";
cin>>i;
cout<<"输入插入数据:";
cin>>e;
cout<<"在链表第"<<i<<"个位置前插入元素"<<e;
listinsert(l,i,e);;
display(l);
cout<<"输入要删除的位置:";
cin>>i;
cout<<"删除链表第"<<i<<"个位置元素"<<m;
listdelete(l,i);
display(l);
}
STL篇list
定义
#include<list>
using namespace std;
list<类型>名字;
常用函数
assign()给list赋值
back()返回最后一个元素
begin()返回指向第一个元素的迭代器
clear()删除所有元素
empty()如果list是空的则返回true
end()返回末尾的迭代器
erase()删除一个元素
front()返回第一个元素
get_allocator()返回list的配置器
insert(iteator,x)插入一个元素x到元素迭代其iteator之前,一般iteator=find(list.begin(),list.end(),3)
max_size()返回list能容纳的最大元素数量
merge(list<T> &x)将x合并到*this
pop_back()删除最后一个元素
pop_front()删除第一个元素
push_back()在list的末尾添加一个元素
push_front()在list的头部添加一个元素
rbegin()返回指向第一个元素的逆向迭代器
remove()从list删除元素
remove_if()按指定条件删除元素
rend()指向list末尾的逆向迭代器
resize()改变list的大小
reverse()把list的元素倒转
size()返回list中的元素个数
sort()给list排
splice(iterator position ,list &x)// list.splice(position,list2)//list2合并到list中position 之前
splice(iterator position ,list &x,iterator i)//元素插入到list中position之前
splice(iterator position ,list &x,iterator first,iterator last)//first-last 之间的元素插入到 list中position之前
swap()交换两个list
unique()删除list中重复的元素