线性表:用于存放非大量数据的一种结构。
线性表有两种实现方式:数组实现和链表实现。
1.顺序表
线性表的数组实现,其存放在内存某连续空间中。
顺序表存取元素操作O(1)。
顺序表的插入和删除操作,其代价为O(n)。
顺序表有静态数组和动态数组两种实现,区别就是静态数组大小固定,动态数组可更改大小,动态数组要使用new 或 malloc方式分配内存,用delete或free释放内存。
2.单链表
单链表以链接方式存储,每个节点都有两部分组成:data和link指针。
链表中的元素在物理内存上一般不是连续存放的,在逻辑上,各个元素是通过link指针连接起来。
链表结点的定义:
struct node{
T data;
struct node *next;
};
链表的操作:
1)插入
2)删除
#include<iostream>
using namespace std;
struct node{
char *c;
node *next;
}*head,*tail; //head指向链表头,tail指向链表尾
/*
*链表的插入,删除。
*/
void add_new_node(struct node *newnode){ //从链表尾端插入结点
if(head == NULL){
head = newnode;
tail = newnode;
newnode->next = NULL;
}
else {
tail->next = newnode;
newnode->next = NULL;
tail = newnode;
}
}
bool insert(int x, char *c){ //newnode 是要插入的结点,x是要插入的位置,x表示插入成功后新节点为第x个结点,x=0表示插入链表最前端,插入成功返回true,否则返回false
struct node *newnode = new node();
newnode->c = new char[10];
memcpy(newnode->c,c,10);
if(head==NULL||x==0){ //链表为空或者插入位置为链表最前端
newnode->next=head;
head=newnode;
if(head==NULL)tail = newnode;
}
else{
struct node *first=head;
int i;
for(i=1;i<x;i++) //寻找插入位置,从第一个结点开始检查
if(first==NULL)break;
else first=first->next;
if(first==NULL){ //找到位置,first是第x-1个结点,将新节点插入到first后面,使新节点成为第x个结点(x=1,2。。)
cerr<<"insert:无效的位置"<<endl;
return false;
}
else{
newnode->next=first->next;
first->next=newnode;
}
if(newnode->next==NULL) tail = newnode; //若插入位置是链表末尾,则tail指向新节点
}
return true;
}
bool remove (int x,char *c){ //删除链表中第x个结点,并将删除结点放进c返回i=(1,2....)
struct node *first=head;
if(x<=0){cerr<<"remove:错误的位置!"<<endl;return false;}
if(x==1){
head=first->next;
if(first->next==NULL)
tail=NULL;
memcpy(c,first->c,10);
return true;
}
int i;
for(i=1;i<x-1;i++) //寻找第x个结点,first存放的是第x个结点的前一个结点
if(first==NULL)break;
else first=first->next;
if(first == NULL||first->next==NULL){
cerr<<"remove:错误的位置!"<<endl;
return false;
}
node *del = first->next;
first->next = del->next;
delete del->c;
memcpy(c,del->c,10);
return true;
}
int main(){
head = NULL;
tail = NULL;
char *get=new char[10];
//从结尾插入
cin>>get;
while(strcmp(get,"#")!=0){
struct node *newnode = new struct node();
newnode->c = new char[10];
memcpy(newnode->c,get,10);
add_new_node(newnode);
cin>>get;
}
//插入验证
char *p = new char[10];
p = "zcx";
insert(2,p);
insert(3,p);
insert(1,p);
insert(0,p);
insert(6,p);
//删除验证
char *del = new char[10];
remove(1,del);
remove(2,del);
remove(3,del);
remove(7,del);
//输出验证
cout<<"-----------------output-----------------"<<endl;
struct node *first = head;
while(first!=tail->next){
cout<<first->c<<endl;
first = first->next;
}
return 0;
}
结果:
还有一些链表形式,比如:带附加头结点的链表,双向链表,循环链表。
总结:
了解了线性表,我们可以看出:
顺序表在取元素时,可以直接存取,单链表则不行。
单链表在插入,删除操作上较为方便,快捷,顺序表代价较大。
链表不限长度,顺序表大小固定。
算是数据结构复习的开始吧!多写,多练!