在使用头插法初始化链表时,修改头结点的指针域,将新结点放在链表里:front->next=s;是什么意思
时间: 2023-05-23 15:00:57 浏览: 174
这意味着将新节点 s 添加到链表中,并使其成为新的头节点。具体来说,链表的头指针 front 指向新插入的节点 s 的下一个节点,而 s 的指针指向原来的头节点。这样做可以快速地在链表的开头插入节点,而不需要遍历整个链表。
相关问题
优化这段代码package park; //设计链队数据结构及其基本操作 public class Queue { private QueueNode front;//队首指针 private QueueNode rear;//队尾指针 //链队列类的构造函数 public Queue() { front=rear=null; } //队列置空 public void clear() { front=rear=null; } //队列置空 public boolean isEmpty() { return front==null; } //求队列长度 public int length() { QueueNode p=front; int length=0; while(p!=null) { p=p.next;//指针下移 ++length;//计数器+1 } return length; } //取出队首元素 public Object peek() { if(front!=null)//队列非空 return front.car;//返回队首结点的数据域值 else return null; } //车辆入队 public boolean offer(Car car) { QueueNode p=new QueueNode(car);//初始化新结点 if(front!=null)//队列非空 { rear.next=p; rear=p;//改变队尾位置 } else { front=rear=p; } return true; } public Object poll() { if(front!=null)//队列非空 { QueueNode p=front;//p指向队首结点 front=front.next;//队首结点出列 if(p==rear)//被删除的结点是队尾结点时 rear=null; return p.car;//返回队首结点的数据域值 } else return null; } //输出队列中的所有数据元素(从头到尾) public void display() { QueueNode p=front; while(p!=null) { System.out.println(p.car+","); p=p.next; } } }
可以考虑以下几个优化点:
1. 使用泛型
在Queue类中使用泛型,以支持不同类型的数据元素。修改Queue类声明如下:
```
public class Queue<T> {
private QueueNode<T> front;//队首指针
private QueueNode<T> rear;//队尾指针
//...
}
```
2. 使用单向链表
Queue类中使用的是双向链表,但实际上队列只需要一个方向的指针即可。因此,可以将QueueNode类改为单向链表节点,修改QueueNode类声明如下:
```
public class QueueNode<T> {
public T car;//数据域
public QueueNode<T> next;//指针域
public QueueNode(T car) {
this.car = car;
next = null;
}
}
```
同时,修改Queue类中的offer和poll方法实现,去掉对prev指针的处理。
3. 优化长度计算
在length方法中,每次循环都需要对计数器加一,可以改为使用for循环遍历。
修改length方法实现如下:
```
public int length() {
int length = 0;
for (QueueNode<T> p = front; p != null; p = p.next) {
length++;
}
return length;
}
```
4. 优化入队操作
在offer方法中,每次插入新节点都需要判断队列是否为空,可以将这部分代码提取到Queue类的构造函数中,初始化时就将队首和队尾指针都设为null。
修改Queue类声明和构造函数实现如下:
```
public class Queue<T> {
private QueueNode<T> front;//队首指针
private QueueNode<T> rear;//队尾指针
public Queue() {
front = rear = null;
}
//...
}
```
同时,在offer方法中,可以直接将新节点插入到rear节点后面,再将rear指向新节点。如果队列为空,直接将front和rear都指向新节点。
修改offer方法实现如下:
```
public boolean offer(T car) {
QueueNode<T> p = new QueueNode<>(car);//初始化新结点
if (front != null) {//队列非空
rear.next = p;
rear = p;//改变队尾位置
} else {
front = rear = p;
}
return true;
}
```
5. 优化出队操作
在poll方法中,需要先判断队列是否为空,可以将这部分代码提取到isEmpty方法中,避免重复判断。
修改isEmpty方法实现如下:
```
public boolean isEmpty() {
return front == null;
}
```
同时,在poll方法中,可以直接将front指向下一个节点即可。如果队列为空,直接返回null。
修改poll方法实现如下:
```
public T poll() {
if (!isEmpty()) {//队列非空
QueueNode<T> p = front;//p指向队首结点
front = front.next;//队首结点出列
if (p == rear) {//被删除的结点是队尾结点时
rear = null;
}
return p.car;//返回队首结点的数据域值
} else {
return null;
}
}
```
6. 优化显示操作
在display方法中,每次循环都需要输出一个逗号,可以改为先输出第一个节点的数据,再循环输出后面的节点数据并加上逗号。
修改display方法实现如下:
```
public void display() {
if (front != null) {
System.out.print(front.car);
QueueNode<T> p = front.next;
while (p != null) {
System.out.print("," + p.car);
p = p.next;
}
}
System.out.println();
}
```
//乘客节点 typedef struct CustomerNode { char name[10];//客户姓名 int clientTickets;//客户订票量 char identification[20];//客户身份证号码 int rank;//座位等级 CustomerNode *next; } CustomerNode, *CusLinkList; //候补队列中的节点 typedef struct WaitPassenger { char name[10];//姓名 char identification[20]; //身份证 int preTickets;//预定的票量 struct WaitPassenger *next; } WaitQNode, *PWait; //候补队列 typedef struct Queue { PWait front;//等候替补客户名单域的头指针 PWait rear;//等候替补客户名单域的尾指针 } LinkQueue; //封装乘客的姓名和订票量和身份证 //用于候补客户出队时把关键字返回 typedef struct NameAndNumAndID { char name[10];//姓名 char identification[20]; //身份证号码 int num;//订票量 } NameAndNumAndID; //车次节点 typedef struct Flight { char startPoint[20];//起点站名 char destination[20];//终点站名 char flightCodeID[20];//车次ID(相当于主键) char planeNum[20];//列车号 char day[20];//出发日期(星期几) int totalTickets;//乘员定额(总票数) int left;//总余票量 int leftEconomicTicket; //二等座剩余量 int leftBusinessTicket; //一等座剩余量 Flight *next; CusLinkList cusLinkList;//乘员名单域,指向乘员名单链表的头指针 LinkQueue waitQueue1;//二等座候补,等候替补的客户名单域,指向一个队列 LinkQueue waitQueue2;//一等座候补,等候替补的客户名单域,指向一个队列 } Flight, FlightNode, *PFlight; //定义全局指针变量pFlight,车次链表的头指针 Flight *pFlight; //初始化车次链表pFlight = (Flight *) malloc(sizeof(Flight));//申请头结点的空间if (pFlight == NULL) exit(0);pFlight->next = NULL; 用c语言实现该结构体的文件读写操作并给出具体代码
以下是实现该结构体的文件读写操作的具体代码:
// 写入车次信息到文件中
void writeFlightToFile(Flight* pFlight, char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "wb")) == NULL) {
printf("Cannot open file.\n");
return;
}
fwrite(pFlight, sizeof(Flight), 1, fp);
Flight* p = pFlight->next;
while (p != NULL) {
fwrite(p, sizeof(Flight), 1, fp);
p = p->next;
}
fclose(fp);
}
// 从文件中读取车次信息
Flight* readFlightFromFile(char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "rb")) == NULL) {
printf("Cannot open file.\n");
return NULL;
}
Flight* pFlight = (Flight*)malloc(sizeof(Flight));
if (pFlight == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
fread(pFlight, sizeof(Flight), 1, fp);
Flight* p = pFlight;
while (!feof(fp)) {
Flight* q = (Flight*)malloc(sizeof(Flight));
if (q == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
fread(q, sizeof(Flight), 1, fp);
p->next = q;
p = q;
}
p->next = NULL;
fclose(fp);
return pFlight;
}
// 写入乘员信息到文件中
void writeCustomerToFile(CusLinkList cusLinkList, char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "wb")) == NULL) {
printf("Cannot open file.\n");
return;
}
CustomerNode* p = cusLinkList->next;
while (p != NULL) {
fwrite(p, sizeof(CustomerNode), 1, fp);
p = p->next;
}
fclose(fp);
}
// 从文件中读取乘员信息
CusLinkList readCustomerFromFile(char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "rb")) == NULL) {
printf("Cannot open file.\n");
return NULL;
}
CusLinkList cusLinkList = (CusLinkList)malloc(sizeof(CustomerNode));
if (cusLinkList == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
cusLinkList->next = NULL;
CustomerNode* p = cusLinkList;
while (!feof(fp)) {
CustomerNode* q = (CustomerNode*)malloc(sizeof(CustomerNode));
if (q == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
fread(q, sizeof(CustomerNode), 1, fp);
p->next = q;
p = q;
}
p->next = NULL;
fclose(fp);
return cusLinkList;
}
// 写入候补客户信息到文件中
void writeWaitPassengerToFile(LinkQueue waitQueue, char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "wb")) == NULL) {
printf("Cannot open file.\n");
return;
}
PWait p = waitQueue.front;
while (p != NULL) {
fwrite(p, sizeof(WaitQNode), 1, fp);
p = p->next;
}
fclose(fp);
}
// 从文件中读取候补客户信息
LinkQueue readWaitPassengerFromFile(char* fileName) {
FILE* fp;
if ((fp = fopen(fileName, "rb")) == NULL) {
printf("Cannot open file.\n");
LinkQueue queue = { NULL, NULL };
return queue;
}
LinkQueue queue = { NULL, NULL };
PWait p = NULL;
while (!feof(fp)) {
PWait q = (PWait)malloc(sizeof(WaitQNode));
if (q == NULL) {
printf("Memory allocation failed.\n");
return queue;
}
fread(q, sizeof(WaitQNode), 1, fp);
q->next = NULL;
if (queue.front == NULL) {
queue.front = q;
p = q;
}
else {
p->next = q;
p = q;
}
}
fclose(fp);
queue.rear = p;
return queue;
}
阅读全文