6.2单链表
来源:互联网 发布:电影源码带采集 编辑:程序博客网 时间:2024/05/22 00:44
1.特征:
①链表中的元素个数可以根据需要增加和减少,不像数组,在声明之后就固定不变;
②元素的位置可以变化,即可以从某个位置删除,然后再插入到一个新的地方;
2.组成:数据成员和指针存放下一个结点的地址(链表中的各节点在内存的存储地址不是连续的)
3.基本操作:
(1)创建链表是指,从无到有地建立起一个链表,即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。
(2)检索操作是指,按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,称为检索失败。
(3)插入操作是指,在结点ki-1与ki之间插入一个新的结点k’,使线性表的长度增1,且ki-1与ki的逻辑关系发生如下变化:插入前,ki-1是ki的前驱,ki是ki-1的后继;插入后,新插入的结点k’成为ki-1的后继、ki的前驱。
(4)删除操作是指,删除结点ki,使线性表的长度减1,且ki-1、ki和ki+1之间的逻辑关系发生如下变化:删除前,ki是ki+1的前驱、ki-1的后继;删除后,ki-1成为ki+1的前驱,ki+1成为ki-1的后继.
(5)打印输出
4.链表结构体定义:struct node { int num; struct node *next; }
6.结点指针定义:node *p;
7.结点存储空间申请、释放:p = new node;/delete p;
8.种类:链表又分为单链表、双向链表和循环链表
9.创建:
1 ) 定义链表的数据结构。
2 ) 创建一个空表。
3 ) 利用new( )函数向系统申请分配一个节点。
4 ) 将新节点的指针成员赋值为空(保证最后一个元素指针指向NULL)。若是空表,将新节点连接到表头;若是非空表,将新节点接到表尾。
5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束。
</pre>典型的链表创建、遍历模板:<pre name="code" class="cpp">#include<stdio.h> #include<malloc.h> struct node { int data ; //数据域 struct node *next ; //指针域,指向下一个结点}; int main() { int n; //将要输入的结点的个数 scanf("%d",&n); struct node *head = (struct node *)malloc(sizeof(struct node)); //为头结点申请存储空间 head->next = NULL; //现在是空链表,头结点的next为空 struct node *tail = head; //tail是指向链表的最后一个结点 for(int i = 1;i <= n;i++ ) { struct node *p=(struct node *)malloc(sizeof(struct node)); //为新结点申请存储空间 scanf("%d",&p->data); //输入新结点的数据 p->next=head->next;; //因为要与输入顺序一致,所以每次输入的值为当前链表的第一个结点 head->next=p; } struct node *s=head->next; //将s指向链表的第一个结点 while(s->next!=NULL) //判断是否是链表最后一个元素就是要判断该元素的next指针是否为空 { printf("%d ",s->data); s=s->next; //s移向先一个结点 } printf("%d\n",s->data); //输出最后一个结点的数据并输出换行 return 0; }10.例题:UVA-11988 这个代码会TLE,但是思路对,这是建表的一个好的练习
#include<stdio.h>#include<time.h>#include<string.h>#include<string>#include<stdlib.h>#include<iostream>#include<vector>using namespace std;struct node{ char n;node *next;};int main(){ char t[100005]; while(scanf("%s",t) != EOF) { node *last = new node; //创建尾部, last->next =NULL; //指明尾部指针 node *tou = last; //创建头部并指明头部指针 node *lastt = last; int len = strlen(t); for(int i = 0;i < len;i++) { if(t[i] == '[') { last = tou; last->next = tou->next; } else if(t[i] == ']') { node *temp = last; while(temp->next != NULL) { temp = temp->next; } last = temp; } else { node *u = new node; //创建子节点 if(last->next == NULL) //接上元素 u->next = NULL; else //插入元素 u->next = last->next; last->next = u; u->n = t[i]; last = u; //子节点移动 } } node *u = tou->next; while(1) { if(u == NULL) break; printf("%c",u->n); u = u->next; } printf("\n"); } return 0;}以下是刘汝佳的思路:
#include<stdio.h>#include<iostream>#include<string>#include<stack>#include<string.h>using namespace std;int last,cur,next[100005];char s[100005];int main(){ while(scanf("%s",s+1)!=EOF) { int len=strlen(s+1); last=cur=0; next[0]=0; for(int i=1;i<=len;i++) { if(s[i]=='[') cur=0; else if(s[i]==']') cur=last; else { next[i]=next[cur]; next[cur]=i; if(cur == last) last = i; cur = i; } } for(int i=next[0];i!=0;i=next[i]) printf("%c",s[i]); printf("\n"); } return 0;}
11.STL链表:
①定义:list<int(任意类型)> name;
②头文件:#include<list>
③push_back()、push_front():往链表后面/前面填元素
④empty():判断链表是否为空
⑤begin()、end():返回链表的第一、最后一个元素
⑥链表遍历:
#include <iostream>#include <string>#include <list>int main (void){ list<string> Milkshakes; list<string>::iterator MilkshakeIterator; //定义迭代器类型 Milkshakes.push_back("Chocolate"); Milkshakes.push_back("Strawberry"); Milkshakes.push_front("Lime"); Milkshakes.push_front("Vanilla"); Milkshakes.push_front("The Milkshake Menu"); Milkshakes.push_back("*** Thats the end ***"); for (MilkshakeIterator=Milkshakes.begin();MilkshakeIterator!=Milkshakes.end();++MilkshakeIterator) //遍历链表(访问了链表中的所有元素),注意不包含最后一个元素 cout << *MilkshakeIterator << endl;}
注:这个list容器,就象你所想的,它不支持在iterator加一个数来指向隔一个的对象。 就是说,我们不能用Milkshakes.begin()+2来指向list中的第三个对象,因为STL的list是以双链的list来实现的, 它不支持随机存取。
⑦for_each()遍历:
#include <iostream.h>#include <string>#include <list>#include <algorithm> PrintIt (string& StringToPrint){ cout << StringToPrint << endl;} int main (void){ list<string> FruitAndVegetables; FruitAndVegetables.push_back("carrot"); FruitAndVegetables.push_back("pumpkin"); FruitAndVegetables.push_back("potato"); FruitAndVegetables.push_front("apple"); FruitAndVegetables.push_front("pineapple"); for_each (FruitAndVegetables.begin(), FruitAndVegetables.end(), PrintIt); //最后一个是要做的事(一定要是函数吗?)}
⑧count():
#include <list>#include <algorithm>int main (void){ list<int> Scores; Scores.push_back(100); Scores.push_back(80); Scores.push_back(45); Scores.push_back(75); Scores.push_back(99); Scores.push_back(100); int NumberOf100Scores(0); NumberOf100Scores = count(Scores.begin(), Scores.end(), 100); //当元素为100时,<span style="font-family: Arial, Helvetica, sans-serif;">NumberOf100Scores自增</span> cout << "There were " << NumberOf100Scores << " scores of 100" << endl;}
⑨count_if():
⑩find():
#include <string>#include <list>#include <algorithm>int main (void){ list<string> Fruit; list<string>::iterator FruitIterator; Fruit.push_back("Apple"); Fruit.push_back("Pineapple"); Fruit.push_back("Star Apple"); FruitIterator = find (Fruit.begin(), Fruit.end(), "Pineapple"); //返回值是一个迭代器 if (FruitIterator == Fruit.end()) cout << "Fruit not found in list" << endl; else cout << *FruitIterator << endl;}
⑾remove():用remove()算法返回一个指向新的list的结尾的iterator。从开始到这个新的结尾(不含新结尾元素)的范围 包含了remove后剩下所有元素。你可以用list成员函数erase函数来删除从新结尾到老结尾的部分。一共有两种remove
#include <string> #include <list>#include <algorithm>PrintIt(string& AString) { cout << AString << endl; }int main (void){ list<string> Birds; list<string>::iterator NewEnd; Birds.push_back("cockatoo"); Birds.push_back("galah"); Birds.push_back("cockatoo"); Birds.push_back("rosella"); Birds.push_back("king parrot"); cout << "Original list" << endl; for_each(Birds.begin(), Birds.end(), PrintIt); NewEnd = remove(Birds.begin(), Birds.end(), "cockatoo"); //最后一个输入要删除的元素,返回新的结尾迭代器 cout << endl << "List according to new past the end iterator" << endl; for_each(Birds.begin(), NewEnd, PrintIt); cout << endl << "Original list now. Care required!" << endl; for_each(Birds.begin(), Birds.end(), PrintIt);}
#include <string> //#include <list>#include <algorithm>PrintIt (const string& StringToPrint){cout << StringToPrint << endl;} int main (void){list<string> Birds;Birds.push_back("cockatoo");Birds.push_back("galah");Birds.push_back("cockatoo");Birds.push_back("rosella");Birds.push_back("corella");cout << "Original list with cockatoos" << endl;for_each(Birds.begin(), Birds.end(), PrintIt);Birds.remove("cockatoo");cout << "Now no cockatoos" << endl;for_each(Birds.begin(), Birds.end(), PrintIt);}
⑿insert() :
#include <list> int main (void){ list<int> list1; for (int i = 0; i < 10; ++i) list1.push_back(i); list1.insert(list1.begin(), -1); list1.insert(list1.end(), 10); int IntArray[2] = {11,12}; list1.insert(list1.end(), &IntArray[0], &IntArray[2]);}
⒀
- 6.2单链表
- 6.2
- 6.2
- 6.2
- 6.2
- 6.2
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 单链表
- 继承BaseHTTPRequestHandler 重写 do_XX 和HTTPServer的使用
- winform 五子棋 判断输赢
- hdu 1175 连连看(模拟循环队列)
- POJ3264_Balanced Lineup(线段树/单点更新)
- Python 字符串
- 6.2单链表
- 代理类
- C++ MFC连接mysql
- 黑马程序员_面向对象_继承多态
- 北大oj--1050
- 格式化时间
- 二分图匹配之匈牙利算法和 二分图匹配的几种题型
- Message Flood
- HDU 1026 Ignatius and the Princess I 记录 路径广搜